Skip to content

⚡️ Use TypeAdapter.validate_json instead of json.loads#13951

Open
dolfinus wants to merge 1 commit intofastapi:masterfrom
dolfinus:feature/pydanticv2-validate-json
Open

⚡️ Use TypeAdapter.validate_json instead of json.loads#13951
dolfinus wants to merge 1 commit intofastapi:masterfrom
dolfinus:feature/pydanticv2-validate-json

Conversation

@dolfinus
Copy link
Contributor

@dolfinus dolfinus commented Jul 30, 2025

#14962 replaced json.dumps with pydantic v2 TypeAdapter.serialize_json(). This is the same, but for body parsing - replace json.loads with TypeAdapter.validate_json().
See also #13949

Now this gives only a moderate speedup, nothing huge. The larger the request body, the larger the speedup.
Currently optimization can be applied only to POST handler with just one body field.

Small benchmark

requirements.txt

fastapi
locust
py-spy

app.py

from http import HTTPStatus

from fastapi import FastAPI, Response
from pydantic import BaseModel

app = FastAPI()

class SimpleModel(BaseModel):
    a: str


@app.post("/data")
async def create_item(data: SimpleModel):
    return Response(status_code=HTTPStatus.NO_CONTENT)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

locustfile.py

import json

from locust import FastHttpUser, TaskSet, task


class FastAPITask(TaskSet):
    data = json.dumps({"a": "abc" * 10000})
    headers = {
        "Content-Type": "application/json",
    }

    @task
    def push_data(self):
        with self.user.rest(
            "POST",
            "data",
            data=self.data,
            headers=self.headers,
            name="/data",
        ) as response:
            response.js


class FastAPIUser(FastHttpUser):
    host = "http://localhost:8000/"
    tasks = [FastAPITask]
locust --web-host=0.0.0.0 --processes 4 FastAPIUser
record --duration 600 --output flamegraph.svg -- python -m uvicorn app:app --host 0.0.0.0 --port 8000 --log-level=warning

Before - 2228RPS, json.loads took 9.8% and type_adapter.validate_python took 1% = 10% combined
fastapi_with_json_loads.tar.gz
fastapi_with_json_loads

After - 2570RPS, type_adapter.validate_json took 7.17%
fastapi_with_typeadapter_json.tar.gz
fastapi_with_typeadapter_json

@dolfinus dolfinus force-pushed the feature/pydanticv2-validate-json branch 12 times, most recently from a558ae5 to 3160247 Compare July 30, 2025 18:18
@YuriiMotov YuriiMotov changed the title ✨ Use TypeAdapter.validate_json for Pydantic v2 ♻️ Use TypeAdapter.validate_json for Pydantic v2 Aug 1, 2025
@github-actions github-actions bot added the conflicts Automatically generated when a PR has a merge conflict label Sep 20, 2025
@github-actions
Copy link
Contributor

This pull request has a merge conflict that needs to be resolved.

@dolfinus dolfinus force-pushed the feature/pydanticv2-validate-json branch from 3160247 to 79b4288 Compare February 23, 2026 18:50
@github-actions github-actions bot removed the conflicts Automatically generated when a PR has a merge conflict label Feb 23, 2026
@codspeed-hq
Copy link

codspeed-hq bot commented Feb 23, 2026

Merging this PR will improve performance by 24.27%

⚡ 2 improved benchmarks
✅ 18 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
test_async_receiving_large_payload 11.8 ms 9.5 ms +24.27%
test_sync_receiving_large_payload 12 ms 9.7 ms +23.82%

Comparing dolfinus:feature/pydanticv2-validate-json (e26fe00) with master (0cf27ec)1

Open in CodSpeed

Footnotes

  1. No successful run was found on master (2f9c914) during the generation of this report, so 0cf27ec was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 23, 2026

📝 Docs preview

Last commit e26fe00 at: https://b828457f.fastapitiangolo.pages.dev

Modified Pages

@dolfinus dolfinus force-pushed the feature/pydanticv2-validate-json branch from 79b4288 to 05540da Compare February 23, 2026 19:17
@dolfinus dolfinus changed the title ♻️ Use TypeAdapter.validate_json for Pydantic v2 ♻️ Use TypeAdapter.validate_json instead of json.loads Feb 23, 2026
@dolfinus dolfinus force-pushed the feature/pydanticv2-validate-json branch 2 times, most recently from fed22fa to 4a76701 Compare February 23, 2026 20:36
@dolfinus dolfinus force-pushed the feature/pydanticv2-validate-json branch from 4a76701 to e26fe00 Compare February 23, 2026 21:30
@dolfinus dolfinus changed the title ♻️ Use TypeAdapter.validate_json instead of json.loads ⚡️ Use TypeAdapter.validate_json instead of json.loads Feb 23, 2026
@dolfinus dolfinus marked this pull request as ready for review February 23, 2026 21:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants