FastAPI Upload File Size Fix
In this tutorial, you'll learn about FastAPI Upload File Size Fix. We cover key concepts, practical examples, and best practices.
The Problem
FastAPI accepts uploaded files of any size by default. A 10GB upload can crash your server, exhaust memory, or cause denial of service.
Quick Fix
Wrong — no size limit on file uploads
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/upload")
async def upload(file: UploadFile = File(...)):
content = await file.read() # Reads entire file into memory
return {"size": len(content)}
Output: Any file size is accepted. A large file consumes all available memory.
Correct — validate file size
from fastapi import FastAPI, File, UploadFile, HTTPException
MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
@app.post("/upload")
async def upload(file: UploadFile = File(...)):
if file.size and file.size > MAX_FILE_SIZE:
raise HTTPException(
status_code=413,
detail=f"File too large. Max {MAX_FILE_SIZE // 1024 // 1024}MB"
)
content = await file.read()
if len(content) > MAX_FILE_SIZE:
raise HTTPException(
status_code=413,
detail="File too large"
)
return {"filename": file.filename, "size": len(content)}
Streaming upload to disk (avoid memory issues)
from fastapi import UploadFile
import aiofiles
MAX_SIZE = 100 * 1024 * 1024
@app.post("/upload-large")
async def upload_large(file: UploadFile = File(...)):
total = 0
async with aiofiles.open(f"/tmp/{file.filename}", "wb") as f:
while chunk := await file.read(1024 * 1024): # 1MB chunks
total += len(chunk)
if total > MAX_SIZE:
raise HTTPException(status_code=413, detail="File too large")
await f.write(chunk)
return {"filename": file.filename, "size": total}
Global upload size limit with middleware
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
class MaxSizeMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
content_length = request.headers.get("content-length")
if content_length and int(content_length) > 50 * 1024 * 1024:
return PlainTextResponse("File too large", status_code=413)
return await call_next(request)
app = FastAPI()
app.add_middleware(MaxSizeMiddleware)
Per-endpoint limits
from pydantic import BaseModel
from fastapi import Depends
class UploadLimits(BaseModel):
max_size: int = 10 * 1024 * 1024
def get_limits(endpoint: str):
limits = {
"/upload-avatar": 5 * 1024 * 1024,
"/upload-video": 500 * 1024 * 1024,
}
return UploadLimits(max_size=limits.get(endpoint, 10 * 1024 * 1024))
@app.post("/upload-avatar")
async def upload_avatar(file: UploadFile = File(...),
limits: UploadLimits = Depends(lambda: get_limits("/upload-avatar"))):
...
Prevention
- Always set a maximum upload size for public endpoints.
- Stream large uploads to disk instead of reading into memory.
- Enforce limits globally via middleware and per-endpoint as needed.
Common Mistakes with upload file size
- Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
- Non-exhaustive pattern matches that compile with warnings then crash at runtime
- Misunderstanding that
Stringis[Char]with poor performance for large text operations
These mistakes appear frequently in real-world FASTAPI code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro