Absinthe
02 / 02

Absinthe: Subscriptions, Dataloader & the N+1 Problem

Absinthe: Subscriptions, Dataloader & the N+1 Problem

The N+1 Query Problem

A naive resolver for a list's nested field can trigger one extra database query per item -- resolving 50 users' posts naively means 50 separate queries. Absinthe commonly integrates with the Dataloader library to batch and deduplicate these into efficient, minimal queries.

Real-Time Subscriptions

subscription do
  field :user_created, :user do
    config fn _args, _info -> {:ok, topic: "users"} end
  end
end

# When triggered elsewhere:
Absinthe.Subscription.publish(MyAppWeb.Endpoint, user, user_created: "users")

# Clients connected over Phoenix Channels get pushed the update --
# no polling required

Interfaces

interface :search_result do
  field :title, :string
  resolve_type fn
    %Article{}, _ -> :article
    %Video{}, _ -> :video
  end
end

# Lets a field return either Article or Video, with clients
# using fragments to request type-specific fields

Guarding Against Expensive Queries

Because a client can request arbitrarily deep nested data in one query, Absinthe supports complexity analysis and depth-limiting middleware -- letting a team reject or throttle overly expensive requests before they strain the server.

Why GraphQL Over REST Here

A client can request exactly the fields it needs in a single query, avoiding REST's common pattern of over-fetching or needing multiple round-trips to assemble a complete view -- and adding new schema fields later doesn't break existing clients, since they only ever ask for the fields they already request.

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free