Description
Update: See this comment for the actual action items on this issue.
Describe the bug:
After updating our application to use elastic-apm 6.12, we are seeing on average 40% higher latency compared to 6.11. The increase is generally lower when the request payload is on the low end (~10 KB) and reaches from 70% to as much as 500% higher with larger payloads (>50KB).
To Reproduce
- Create a FastAPI app with a "/save" endpoint which accepts an arbitrary (e.g. Request(id=0,data={...}) request object
- Create an elasticapm client with default capture_body=False and add to the app as middleware
- Wrap the endpoint method with an elasticapm.async_capture_span decorator
- Build the FastAPI app environment with elastic-apm==6.11
- Call the save endpoint with 50KB test requests at a rate of ~250 TPM and record the resulting average latency
- Rebuild the app with elastic-apm==6.12 and repeat the load test
Environment (please complete the following information)
- OS: Linux
- Python version: 3.10
- Framework and version [e.g. Django 2.1]: FastAPI 0.103.1
- APM Server version: v8.5.0
- Agent version: 6.11.0, >=6.12.0 (observed in 6.12, 6.13, 6.18, and 6.19)
Additional context
We have been able to isolate the latency issues to the elastic-apm version alone, the issue is seen before and after updating from 6.11 to 6.12 without making any other change. I have not been able to identify the root cause yet but I'm continuing to research and will update this issue as I learn more.
I noticed an interesting pattern in some recent testing with CPU usage reported in Kibana, see attached screenshots. With peak load (250 TPM) and the same length testing window, the max utilization in 6.11 peaks initially but remains flat throughout the rest of the test period whereas 6.12 the utilization rises and falls periodically seemingly at fixed intervals.
-
Agent config options
Click to expand
{'service_name': 'Python-FastAPI-Service', 'server_url': *************, 'secret_token': *************}
-
requirements.txt:
Click to expand
anyio==3.7.1 asn1crypto==1.5.1 boto3==1.28.57 botocore==1.31.85 certifi==2023.11.17 cffi==1.16.0 chardet==5.2.0 charset-normalizer==3.3.2 click==8.1.7 coverage==7.3.2 cryptography==41.0.7 ecs-logging==2.1.0 elastic-apm==6.12.0 exceptiongroup==1.2.0 fastapi==0.103.1 filelock==3.13.1 gunicorn==21.2.0 h11==0.14.0 httpcore==1.0.2 httptools==0.6.1 httpx==0.25.2 idna==3.6 iniconfig==2.0.0 jmespath==1.0.1 libcst==1.1.0 markdown-it-py==3.0.0 mdurl==0.1.2 mypy-extensions==1.0.0 oscrypto==1.3.0 packaging==23.2 pendulum==2.1.2 platformdirs==3.8.1 pluggy==1.3.0 pycparser==2.21 pycryptodomex==3.19.0 pydantic==2.5.2 pydantic-settings==2.1.0 pydantic_core==2.14.5 Pygments==2.16.1 PyJWT==2.8.0 pyOpenSSL==23.3.0 pytest==7.4.3 pytest-cov==4.1.0 pytest-env==1.1.3 python-dateutil==2.8.2 python-dotenv==1.0.0 python-json-logger==2.0.7 pytz==2023.3.post1 pytzdata==2020.1 PyYAML==6.0.1 requests==2.31.0 rich==13.6.0 s3transfer==0.7.0 six==1.16.0 sniffio==1.3.0 snowflake-connector-python==3.2.0 sortedcontainers==2.4.0 starlette==0.27.0 tomli==2.0.1 tomlkit==0.12.3 typer==0.9.0 typing-inspect==0.9.0 typing_extensions==4.9.0 urllib3==1.26.18 uvicorn==0.18.3 uvloop==0.19.0 watchfiles==0.21.0 websockets==12.0 wrapt==1.14.1