Using Alternative JSON Encoders
FastAPI provides specialized response classes for high-performance JSON serialization using the orjson and ujson libraries. While these were previously the recommended way to optimize JSON performance, they are now considered deprecated in modern FastAPI in favor of direct Pydantic serialization.
High-Performance Response Classes
The two primary alternative JSON encoders provided by FastAPI are ORJSONResponse and UJSONResponse, both located in fastapi.responses.
ORJSONResponse
ORJSONResponse uses the orjson library, which is often significantly faster than the standard Python json library. It is particularly useful when dealing with complex data types like NumPy arrays or non-string dictionary keys.
As defined in fastapi/responses.py, ORJSONResponse automatically enables specific orjson options:
class ORJSONResponse(JSONResponse):
def render(self, content: Any) -> bytes:
assert orjson is not None, "orjson must be installed to use ORJSONResponse"
return orjson.dumps(
content, option=orjson.OPT_NON_STR_KEYS | orjson.OPT_SERIALIZE_NUMPY
)
OPT_NON_STR_KEYS: Allows serializing dictionaries with integer or other non-string keys.OPT_SERIALIZE_NUMPY: Enables direct serialization of NumPy arrays.
UJSONResponse
UJSONResponse uses the ujson library. It is another high-performance alternative that focuses on speed and compatibility.
class UJSONResponse(JSONResponse):
def render(self, content: Any) -> bytes:
assert ujson is not None, "ujson must be installed to use UJSONResponse"
return ujson.dumps(content, ensure_ascii=False).encode("utf-8")
The implementation sets ensure_ascii=False by default, which can improve performance and reduce response size when dealing with non-ASCII characters.
Implementation via Protocols
To maintain type safety without forcing a hard dependency on these libraries, FastAPI defines internal protocols in fastapi/responses.py. These protocols, _OrjsonModule and _UjsonModule, describe the expected interface for the underlying libraries:
class _OrjsonModule(Protocol):
OPT_NON_STR_KEYS: int
OPT_SERIALIZE_NUMPY: int
def dumps(self, __obj: Any, *, option: int = ...) -> bytes: ...
class _UjsonModule(Protocol):
def dumps(self, __obj: Any, *, ensure_ascii: bool = ...) -> str: ...
Usage Patterns
You can apply these response classes either to specific routes or globally across your entire application.
Route-Specific Usage
To use an alternative encoder for a single path operation, use the response_class parameter in the decorator. This is demonstrated in docs_src/custom_response/tutorial001b_py310.py:
from fastapi import FastAPI
from fastapi.responses import ORJSONResponse
app = FastAPI()
@app.get("/items/", response_class=ORJSONResponse)
async def read_items():
return [{"item_id": "Foo"}]
Application-Wide Usage
If you want every route in your application to use a specific encoder by default, set the default_response_class in the FastAPI constructor. This pattern is frequently used in performance testing, such as in tests/test_orjson_response_class.py:
from fastapi import FastAPI
from fastapi.responses import ORJSONResponse
app = FastAPI(default_response_class=ORJSONResponse)
@app.get("/orjson_non_str_keys")
def get_orjson_non_str_keys():
# orjson handles non-string keys automatically
return {"msg": "Hello World", 1: 1}
Deprecation and Modern Alternatives
Both ORJSONResponse and UJSONResponse are marked as deprecated in the codebase. The docstrings in fastapi/responses.py explain the reasoning:
FastAPI now serializes data directly to JSON bytes via Pydantic when a return type or response model is set, which is faster and doesn't need a custom response class.
In modern FastAPI, if you define a response_model or use a return type hint, FastAPI uses Pydantic's optimized serialization logic to generate JSON bytes directly. This approach typically outperforms using a custom response class because it avoids the overhead of creating an intermediate Python dictionary before serialization.
Using these deprecated classes will trigger a FastAPIDeprecationWarning, as seen in tests/test_deprecated_responses.py:
@needs_orjson
def test_orjson_response_emits_deprecation_warning():
with pytest.warns(FastAPIDeprecationWarning, match="ORJSONResponse is deprecated"):
ORJSONResponse(content={"hello": "world"})
Requirements
Neither orjson nor ujson are included in the default FastAPI installation. If you choose to use these classes, you must install the libraries manually:
pip install orjson
# or
pip install ujson
If the library is not installed when the render method is called, FastAPI will raise an AssertionError with a descriptive message.