Competitive Analysis

pypaginate v0.2.0 vs the Python pagination ecosystem – an honest, benchmark-backed assessment.


The Ecosystem

Library

Stars

Focus

Backends

fastapi-pagination

1,635

Pagination

19 (SA, Beanie, Tortoise…)

fastapi-filter

302

SA filtering

SQLAlchemy, MongoEngine

sqlakeyset

Keyset pagination

SQLAlchemy

sqlalchemy-pagination

80

Offset pagination

SQLAlchemy

paginate

In-memory pagination

Any sequence

pypaginate

All-in-one

Memory, SQLAlchemy, FastAPI


Feature Comparison

Feature

pypaginate

fastapi-pagination

fastapi-filter

paginate-lib

Offset pagination

yes

yes

no

yes

Cursor/keyset pagination

yes

yes

no

no

In-memory filtering (20 ops)

yes

no

no

no

In-memory sorting (null-aware)

yes

no

no

no

In-memory search (fuzzy+Unicode)

yes

no

no

no

SA filtering (WHERE)

yes

no

yes

no

SA sorting (ORDER BY)

yes

no

no

no

SA search (LIKE/ILIKE)

yes

no

no

no

Full pipeline (filter+sort+search+paginate)

yes

no

no

no

Nested filter groups (And/Or)

yes

no

partial

no

Sync + async auto-detection

yes

yes

no

no

FastAPI integration

yes

yes

yes

no

msgspec fast pages

yes

no

no

no

Type-safe (Elysia-style inference)

yes

partial

no

no

mypy --strict

yes

yes

no

no

pypaginate is the only library that does filter + sort + search + paginate in one call.


Performance Benchmarks (10K items)

All benchmarks run on the same machine, same data, same operations. Competitors that cannot filter/sort use raw Python for those steps plus their own pagination.

Paginate Only (all libraries can do this)

Rank

Library

Median

vs #1

#1

pypaginate

1.2 us

#2

paginate-lib

1.4 us

1.2x

#3

fastapi-pagination

44.5 us

37.6x

SA Paginate Sync (COUNT + OFFSET/LIMIT on same SQLite DB)

Rank

Library

Median

vs #1

#1

pypaginate sync

330 us

#2

sqlakeyset

379 us

1.1x

#3

sqlalchemy-pagination

487 us

1.5x

#4

fastapi-pagination SA

572 us

1.7x

Full Pipeline: filter + sort + paginate

All libraries do the same work. Competitors use raw Python for filter+sort, then their paginate.

Rank

Library

Median

How filter+sort is done

#1

paginate-lib

682 us

Raw Python list comp + sorted()

#2

fastapi-pagination

756 us

Raw Python list comp + sorted()

#3

pypaginate

2.50 ms

Built-in compiled pipeline

Why the gap? Competitors use raw Python list comprehension + sorted() for filter+sort – zero abstraction overhead. pypaginate uses compiled predicates + null-aware sorting – features that have a cost in CPython.

SA Filter (WHERE clause + pagination)

Rank

Library

Median

Note

#1

fastapi-filter

320 us

Builds WHERE clause only (no COUNT/OFFSET)

#2

pypaginate SA

816 us

Full pipeline (WHERE + COUNT + OFFSET/LIMIT)

Why the gap? fastapi-filter only builds the SQL WHERE clause – no database execution. pypaginate does the full pipeline: WHERE + COUNT + OFFSET/LIMIT.


Overhead Breakdown (10K items)

Paginate + serialize adds near-zero overhead. The HTTP layer dominates.

Step

Filter

Sort

Search

Paginate

Ops only

928 us

1.73 ms

8.98 ms

1.2 us

+ Paginate

942 us (+14us)

1.71 ms (+0)

7.76 ms (+0)

+ Serialize

918 us (+0)

1.78 ms (+71us)

8.94 ms (+0)

3.9 us (+2.7us)

+ Full HTTP

11.51 ms (+10.6ms)

10.43 ms (+8.7ms)

18.69 ms (+9.8ms)

8.91 ms (+8.9ms)

Key finding: Paginate and serialize add essentially zero overhead. The HTTP layer (FastAPI request/response encoding) adds roughly 9ms constant – this is FastAPI’s cost, not pypaginate’s.


DX Comparison: Endpoint Code

With fastapi-pagination + fastapi-filter (2 libraries)

from fastapi_pagination import Page, add_pagination, paginate
from fastapi_filter import FilterDepends
from fastapi_filter.contrib.sqlalchemy import Filter

app = FastAPI()
add_pagination(app)

class UserFilter(Filter):
    name__ilike: str | None = None
    age__gte: int | None = None
    class Constants(Filter.Constants):
        model = User

@app.get("/users", response_model=Page[UserSchema])
async def get_users(
    user_filter: UserFilter = FilterDepends(UserFilter),
):
    query = user_filter.filter(select(User))
    return await paginate(query)

With pypaginate v0.2.0 (1 library)

from pypaginate import paginate, OffsetParams, FilterSpec
from pypaginate.adapters.fastapi import OffsetDep
from pypaginate.adapters.sqlalchemy import SQLAlchemyBackend, SQLAlchemyFilterBackend
from pypaginate.engine.pipeline import AsyncPipeline
from pypaginate.engine.paginator import AsyncPaginator

@app.get("/users")
async def get_users(
    params: OffsetDep,
    session: AsyncSession = Depends(get_session),
    name: str | None = Query(None),
    min_age: int | None = Query(None),
):
    filters = []
    if name:
        filters.append(FilterSpec(field="name", operator="contains", value=name))
    if min_age:
        filters.append(FilterSpec(field="age", operator="gte", value=min_age))

    backend = SQLAlchemyBackend(session)
    pipeline = AsyncPipeline(
        AsyncPaginator(backend),
        filter_backend=SQLAlchemyFilterBackend(),
    )
    return await pipeline.execute(select(User), params, filters=filters)

Comparison

Aspect

fastapi-pagination + filter

pypaginate

Libraries needed

2

1

Filter declaration

Declarative (class)

Declarative (FilterDep with FilterField)

Sorting

Built into filter class

SortDep (?sort=name,-age)

Search

Basic (ilike only)

SearchDep + full fuzzy/Unicode/tokens

Type safety

Partial (string operators)

Full (Literal types, protocols)

In-memory support

No

Yes (same API)

Auto OpenAPI for filters

Yes

Yes (FilterDep generates OpenAPI via Pydantic)

Nested filter groups

No

Yes (And/Or builders)


Where pypaginate Wins

  1. Performance: #1 for pagination (1.2us vs paginate-lib 1.4us vs fp 44.5us).

  2. SA Performance: Faster than sqlakeyset and raw SA pagination (330us vs 379us).

  3. Unified library: Filter + sort + search + paginate in one pip install.

  4. Search: Only library with fuzzy matching, Unicode normalization, accent removal.

  5. Type safety: mypy --strict, Elysia-style type inference, Literal operator types.

  6. Architecture: Protocol-based backends, compile-once strategy, __slots__ everywhere.

  7. msgspec acceleration: Near-zero page construction with pypaginate[fast].

  8. Nested filters: And() / Or() groups up to 5 levels deep.

Where pypaginate Lags

  1. DB backends: SQLAlchemy only (competitors support 19 backends).

  2. Full pipeline speed: Behind competitors that use raw Python for filter+sort.

  3. Zero-config middleware: No add_pagination(app) – explicit setup required.

Roadmap

Version

Focus

Status

v0.2.0

Hexagonal architecture, protocol backends, unified paginate(), FilterDep, SortDep, SearchDep

Done

v0.3.0

JSON Logic parser, add_pagination(app), HATEOAS links

Planned

v0.4.0

Multi-backend (Beanie, Tortoise), additional ORM support

Planned

v1.0.0

Rust core extension for 10x filter/search speed

Planned