# Performance issue with an API calling another API

**URL:** <https://discourse.julialang.org/t/performance-issue-with-an-api-calling-another-api/110976>\
**Category:** Web Stack\
**Tags:** question, package, performance, http, oxygenjl\
**Created:** [February 29, 2024, 10:02pm UTC](https://discourse.julialang.org/t/performance-issue-with-an-api-calling-another-api/110976 "2024-02-29T22:02:52Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![AbrJA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abrja/32/207387_2.png) [@AbrJA](https://discourse.julialang.org/u/AbrJA)\
**Post date:** [February 29, 2024, 10:02pm UTC](https://discourse.julialang.org/t/performance-issue-with-an-api-calling-another-api/110976/1 "2024-02-29T22:02:52Z")

</div>

Hi everyone,

Exploring the Oxygen package to build APIs I found this I haven’t been able to solve

1. When I run this API (with a 150 ms sleep to simulate the time taken by a model):

```julia
using Oxygen

@get "/model" function()
    sleep(0.15)
    return json("ok")
end

serve(port = 8001)

```

**I reach about 560 RPS** (with concurrency = 100)

`ab -n1000 -c100 'http://localhost:8001/model'`

```julia
Server Software:        
Server Hostname: localhost
Server Port: 8001

Document Path: /model
Document Length: 4 bytes

Concurrency Level: 100
Time taken for tests: 1.756 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 83000 bytes
HTML transferred: 4000 bytes
Requests per second: 569.62 [#/sec] (mean)
Time per request: 175.556 [ms] (mean)
Time per request: 1.756 [ms] (mean, across all concurrent requests)
Transfer rate: 46.17 [Kbytes/sec] received

```

When I build another Oxygen API consuming the previous one

```julia
using Oxygen
using HTTP

@get "/test" function()
    response = HTTP.get("http://localhost:8001/model")
    return json("ok")
end

serve(port = 8002)

```

**I reach only around 100 RPS** even using 4 threads with serveparallel. I would expect to see an RPS number closer to 560.

`ab -n1000 -c100 'http://localhost:8002/test'`

```julia
Server Software:        
Server Hostname: localhost
Server Port: 8002

Document Path: /test
Document Length: 4 bytes

Concurrency Level: 100
Time taken for tests: 9.815 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 83000 bytes
HTML transferred: 4000 bytes
Requests per second: 101.89 [#/sec] (mean)
Time per request: 981.455 [ms] (mean)
Time per request: 9.815 [ms] (mean, across all concurrent requests)
Transfer rate: 8.26 [Kbytes/sec] received

```

If I do the same with FastAPI

```julia
import requests
from fastapi import FastAPI

app = FastAPI()

@app.get("/test")
def test():
    response = requests.get("http://localhost:8001/model")
    return "ok"

```

**With just one worker** (uvicorn api\_test\_nested:app --host 0.0.0.0 --port 8003 --workers 1) **I get around 220 RPS**

`ab -n1000 -c100 'http://localhost:8003/test'`

```julia
Server Software: uvicorn
Server Hostname: localhost
Server Port: 8003

Document Path: /test
Document Length: 6 bytes

Concurrency Level: 100
Time taken for tests: 4.436 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 149000 bytes
HTML transferred: 6000 bytes
Requests per second: 225.42 [#/sec] (mean)
Time per request: 443.618 [ms] (mean)
Time per request: 4.436 [ms] (mean, across all concurrent requests)
Transfer rate: 32.80 [Kbytes/sec] received

```

I think the issue is in the HTTP.get request on the Julia API maybe there is a better way to do it or ways to speed it up. Any hint is welcome.

Cheers,

Abraham

---

<div class="post-metadata">

**Author:** ![AbrJA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abrja/32/207387_2.png) [@AbrJA](https://discourse.julialang.org/u/AbrJA)\
**Post date:** [March 5, 2024, 12:03am UTC](https://discourse.julialang.org/t/performance-issue-with-an-api-calling-another-api/110976/2 "2024-03-05T00:03:22Z")

</div>

**Progress:**

I changed the `/test` API to **use curl instead of HTTP.jl** and I got a huge improvement so I’m almost sure there is something strange with HTTP.jl

```julia
using Oxygen

@get "/test" function()
    response = run(`curl http://localhost:8001/model`) # instead of HTTP.request("GET", "http://localhost:8001/model")
    return json("ok")
end

serve(port = 8002)

```

**With this small change I go from 100 RPS to about 440 RPS,** much closer to 560 RPS I get from `/model` and twice the RPS from FastAPI with one worker.

Any suggestion is welcome!

---

<div class="post-metadata">

**Author:** ![era127](https://avatars.discourse-cdn.com/v4/letter/e/eb8c5e/32.png) [@era127](https://discourse.julialang.org/u/era127)\
**Post date:** [June 9, 2024, 4:47am UTC](https://discourse.julialang.org/t/performance-issue-with-an-api-calling-another-api/110976/3 "2024-06-09T04:47:05Z")

</div>

Maybe you could try EasyCurl.jl

In my benchmark with one thread, it got to over 510 rps.

---

<div class="post-metadata">

**Author:** ![AbrJA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abrja/32/207387_2.png) [@AbrJA](https://discourse.julialang.org/u/AbrJA)\
**Post date:** [June 13, 2024, 4:11pm UTC](https://discourse.julialang.org/t/performance-issue-with-an-api-calling-another-api/110976/4 "2024-06-13T16:11:52Z")

</div>

I confirm that, it would be interesting to know why it happens or what the issue is with HTTP

```julia
using Oxygen
using EasyCurl

@get "/test" function()
    response = curl_get("http://localhost:8001/model")
    return json("Ok")
end

serve(port = 8002)

```

ab -n1000 -c100 ‘127.0.0.1:8002/test’

```julia
Concurrency Level: 100
Time taken for tests: 1.918 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 89000 bytes
HTML transferred: 4000 bytes
Requests per second: 521.29 [#/sec] (mean)
Time per request: 191.832 [ms] (mean)
Time per request: 1.918 [ms] (mean, across all concurrent requests)
Transfer rate: 45.31 [Kbytes/sec] received

```
