CINXE.COM
Pagination | GraphQL
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="theme-color" content="#111" media="(prefers-color-scheme: dark)"/><meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"/><style>:root{--nextra-primary-hue:319deg;--nextra-primary-saturation:100%;--nextra-navbar-height:4rem;--nextra-menu-height:3.75rem;--nextra-banner-height:2.5rem;--nextra-bg:250,250,250;}.dark{--nextra-primary-hue:319deg;--nextra-primary-saturation:100%;--nextra-bg:27,27,27;}</style><title>Pagination | GraphQL</title><meta property="og:title" content="Pagination | GraphQL"/><meta property="og:image" content="/img/og-image.png"/><meta property="twitter:site" content="@graphql"/><meta name="next-head-count" content="8"/><link rel="preload" href="/_next/static/media/b5c95a22b4347906-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/media/92f44bb82993d879-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/css/cde0c5530d6cb230.css" as="style"/><link rel="stylesheet" href="/_next/static/css/cde0c5530d6cb230.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-c32a8f541f65a415.js" defer=""></script><script src="/_next/static/chunks/framework-c6b0c42f5fb42e03.js" defer=""></script><script src="/_next/static/chunks/main-1a598e82cba69211.js" defer=""></script><script src="/_next/static/chunks/pages/_app-59e41e3cf8666a28.js" defer=""></script><script src="/_next/static/chunks/27af6337-7695a0000d91b781.js" defer=""></script><script src="/_next/static/chunks/4642-240da53c9bd58fb5.js" defer=""></script><script src="/_next/static/chunks/5689-7b4f5ac64417edeb.js" defer=""></script><script src="/_next/static/chunks/2252-ca5e37b793385705.js" defer=""></script><script src="/_next/static/chunks/3993-ab5923ece1113cce.js" defer=""></script><script src="/_next/static/chunks/pages/learn/pagination-6353778d5c3e990c.js" defer=""></script><script src="/_next/static/4210ra6FRMb7c70R92Jlt/_buildManifest.js" defer=""></script><script src="/_next/static/4210ra6FRMb7c70R92Jlt/_ssgManifest.js" defer=""></script><style id="__jsx-2017624775">html{font-family:'__Roboto_Flex_b673aa', '__Roboto_Flex_Fallback_b673aa'}.roboto-mono{font-family:'__Roboto_Mono_43fb55', '__Roboto_Mono_Fallback_43fb55'}</style></head><body><div id="__next"><script>!function(){try{var d=document.documentElement,c=d.classList;c.remove('light','dark');var e=localStorage.getItem('theme');if('system'===e||(!e&&true)){var t='(prefers-color-scheme: dark)',m=window.matchMedia(t);if(m.media!==t||m.matches){d.style.colorScheme = 'dark';c.add('dark')}else{d.style.colorScheme = 'light';c.add('light')}}else if(e){c.add(e|| '')}if(e==='light'||e==='dark')d.style.colorScheme=e}catch(e){}}()</script><div dir="ltr"><script>document.documentElement.setAttribute('dir','ltr')</script><script>try{if(localStorage.getItem("graphqlconf-2024")==='0'){document.body.classList.add('nextra-banner-hidden')}}catch(e){}</script><div class="nextra-banner-container max-md:_sticky _top-0 _z-20 _flex _items-center _h-[var(--nextra-banner-height)] [body.nextra-banner-hidden_&]:_hidden _text-slate-50 dark:_text-white _bg-neutral-900 dark:_bg-[linear-gradient(1deg,#383838,#212121)] _px-2 _ps-10 print:_hidden"><div class="_w-full _truncate _text-center _font-medium _text-sm">📣 GraphQLConf 2025 • Sept 08-10 • Amsterdam • Early bird tickets available & sponsorship opportunities open •<!-- --> <a class="underline after:font-sans after:content-['_→']" href="/conf/2025/">Learn more</a></div><button type="button" aria-label="Dismiss banner" class="_w-8 _h-8 _opacity-80 hover:_opacity-100"><svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" class="_mx-auto _h-4 _w-4"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></button></div><div class="nextra-nav-container _sticky _top-0 _z-20 _w-full _bg-transparent print:_hidden"><div class="nextra-nav-container-blur"></div><nav class="_mx-auto _flex _h-[var(--nextra-navbar-height)] _max-w-[90rem] _items-center _justify-end _gap-4 _pl-[max(env(safe-area-inset-left),1.5rem)] _pr-[max(env(safe-area-inset-right),1.5rem)]"><a class="_flex _items-center hover:_opacity-75 ltr:_mr-auto rtl:_ml-auto" href="/"><svg xmlns="http://www.w3.org/2000/svg" style="fill:color(display-p3 .8824 0 .5961)" viewBox="0 0 367 100" class="nextra-logo h-8" title="GraphQL"><path fill-rule="evenodd" d="m50 6.468 37.7 21.766v43.532L50 93.532 12.3 71.766V28.234zM16.53 30.676v31.976l27.692-47.964zM50 13.14 18.078 68.43h63.844zm27.692 59.52H22.308L50 88.648zm5.778-10.008L55.778 14.688 83.47 30.676z" clip-rule="evenodd"></path><circle cx="14.41" cy="29.45" r="8.91"></circle><circle cx="14.41" cy="70.545" r="8.91"></circle><circle cx="50" cy="91.09" r="8.91"></circle><circle cx="85.585" cy="70.545" r="8.91"></circle><circle cx="85.585" cy="29.455" r="8.91"></circle><circle cx="50" cy="8.91" r="8.91"></circle><path d="M138.875 71.625q-7.812 0-12.125-4.5t-4.562-12.062q-.063-1.876-.063-5.938t.063-5.937q.25-7.563 4.562-12.063t12.125-4.5q5.313 0 8.938 2 3.624 2 5.375 4.75 1.812 2.688 1.937 4.813v.124q0 .501-.375.813-.375.313-.938.313h-1.374q-.562 0-.813-.25t-.5-1q-1.062-3.313-4.125-5.563-3-2.25-8.125-2.25-5.812 0-9.187 3.188-3.313 3.187-3.563 9.937-.062 1.875-.062 5.625t.062 5.625q.25 6.75 3.563 9.938 3.375 3.186 9.187 3.187 5.813 0 9.375-3.312 3.562-3.314 3.562-9.813v-3.187h-10.874q-.625 0-1-.376a1.58 1.58 0 0 1-.375-1.062v-.875q0-.625.375-1 .375-.437 1-.437h13.374q.688 0 1.063.374.375.376.375 1.063v5.5q0 4.999-2 8.813-2 3.811-5.812 5.937-3.813 2.125-9.063 2.125M165.941 71q-.625 0-1-.375t-.375-1V39.938q0-.625.375-1 .375-.438 1-.438h1q.625 0 1 .438.438.375.438 1v2.874q2.25-4.312 8.5-4.312h2.312q.625 0 1 .375t.375 1v.875q0 .625-.375 1t-1 .375h-2.687q-3.75 0-5.938 2.188-2.187 2.187-2.187 5.937v19.375q0 .625-.438 1-.375.375-1 .375zM194.557 71.625q-3 0-5.563-1.25T184.869 67q-1.5-2.126-1.5-4.687 0-4.125 3.313-6.75 3.374-2.625 9.062-3.376l9.875-1.374v-2.188q0-3.438-2.125-5.25-2.063-1.875-6.375-1.875-3.188 0-5.25 1.25-2 1.25-2.562 3-.25.75-.625 1.063-.313.25-.875.25h-.875q-.563 0-1-.376a1.5 1.5 0 0 1-.375-1q0-1.374 1.25-3.187 1.25-1.875 3.875-3.25t6.437-1.375q6.687 0 9.5 3.188 2.813 3.187 2.813 7.75v20.812q0 .625-.375 1-.376.375-1 .375h-1.063q-.625 0-1-.375t-.375-1v-2.937q-1.375 2.061-4.062 3.5-2.626 1.437-7 1.437m.625-3.625q4.561 0 7.5-3 2.937-3 2.937-8.625V54.25l-8.062 1.125q-5.125.687-7.75 2.375T187.182 62q0 2.875 2.375 4.438Q191.994 68 195.182 68M220.752 82.875q-.624 0-1-.375-.375-.375-.375-1V39.875q0-.625.375-1 .376-.375 1-.375h1.063q.625 0 1 .375t.375 1v2.938q3.626-4.938 10.5-4.938 6.75 0 9.937 4.313 3.25 4.25 3.438 10.5.063.624.062 2.062 0 1.437-.062 2.063-.187 6.25-3.438 10.562-3.187 4.25-9.937 4.25-6.813 0-10.5-4.937V81.5q0 .625-.375 1t-1 .375zM233.315 68q5.062 0 7.375-3.187 2.375-3.25 2.562-8.313.063-.625.063-1.75 0-5.813-2.25-9.5-2.25-3.75-7.75-3.75-4.938 0-7.438 3.313-2.5 3.25-2.687 7.687l-.063 2.438.063 2.437a12.8 12.8 0 0 0 1.187 5.125q1.125 2.375 3.375 3.938Q230.002 68 233.315 68M257.068 71q-.625 0-1-.375t-.375-1V28q0-.625.375-1t1-.375h1.063q.625 0 1 .375t.375 1v14.813q1.875-2.439 4.25-3.688 2.437-1.25 6.25-1.25 6.125 0 9.437 3.938 3.313 3.874 3.313 10.062v17.75q0 .625-.375 1t-1 .375h-1.063q-.625 0-1-.375t-.375-1V52.188q0-5.063-2.5-7.876-2.437-2.812-7.062-2.812-4.5 0-7.188 2.875-2.687 2.813-2.687 7.813v17.437q0 .625-.375 1t-1 .375zM321.682 75.063q-.938 0-2-1.438l-2.75-3.812q-3.75 1.812-8.75 1.812-16.062 0-16.5-17.25-.062-1.875-.062-5.25t.062-5.25q.25-8.5 4.625-12.875t11.875-4.375T320.057 31t4.625 12.875q.125 3.75.125 5.25t-.125 5.25q-.312 8.937-4.562 13.125l4 5.625q.187.376.187.688a1.2 1.2 0 0 1-.375.874 1.2 1.2 0 0 1-.875.376zm-13.5-7.188q5.625 0 8.938-3.375 3.375-3.437 3.625-10.437.125-3.75.125-4.938t-.125-4.937q-.25-7-3.625-10.376-3.375-3.437-8.938-3.437-5.562 0-8.937 3.438-3.375 3.375-3.625 10.374-.063 1.875-.063 4.938t.063 4.938q.25 6.999 3.562 10.437 3.375 3.375 9 3.375M336.126 71q-.625 0-1-.375t-.375-1v-41q0-.625.375-1t1-.375h1.188q.625 0 1 .375t.375 1V67.25h21.562q.688 0 1.063.375t.375 1.063v.937q0 .625-.438 1-.375.375-1 .375z"></path></svg></a><a class="_text-sm contrast-more:_text-gray-700 contrast-more:dark:_text-gray-100 max-md:_hidden _whitespace-nowrap _font-medium _subpixel-antialiased" aria-current="true" href="/learn/">Learn</a><div class="_relative" data-headlessui-state=""><button class="_text-sm contrast-more:_text-gray-700 contrast-more:dark:_text-gray-100 _text-gray-600 hover:_text-gray-800 dark:_text-gray-400 dark:hover:_text-gray-200 max-md:_hidden _items-center _whitespace-nowrap _rounded _flex _gap-1" id="headlessui-menu-button-:Rkl56:" type="button" aria-haspopup="menu" aria-expanded="false" data-headlessui-state="">Community<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="_h-[18px] _min-w-[18px] _rounded-sm _p-0.5"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" class="_origin-center _transition-transform _rotate-90"></path></svg></button></div><a class="_text-sm contrast-more:_text-gray-700 contrast-more:dark:_text-gray-100 max-md:_hidden _whitespace-nowrap _text-gray-600 hover:_text-gray-800 dark:_text-gray-400 dark:hover:_text-gray-200" aria-current="false" href="/faq/">FAQ</a><a href="https://spec.graphql.org" target="_blank" rel="noreferrer" class="_text-sm contrast-more:_text-gray-700 contrast-more:dark:_text-gray-100 max-md:_hidden _whitespace-nowrap _text-gray-600 hover:_text-gray-800 dark:_text-gray-400 dark:hover:_text-gray-200" aria-current="false"><span class="after:font-sans after:content-['_↗']">Spec</span></a><a class="_text-sm contrast-more:_text-gray-700 contrast-more:dark:_text-gray-100 max-md:_hidden _whitespace-nowrap _text-gray-600 hover:_text-gray-800 dark:_text-gray-400 dark:hover:_text-gray-200" aria-current="false" href="/blog/">Blog</a><a class="_text-sm contrast-more:_text-gray-700 contrast-more:dark:_text-gray-100 max-md:_hidden _whitespace-nowrap _text-gray-600 hover:_text-gray-800 dark:_text-gray-400 dark:hover:_text-gray-200" aria-current="false" href="/conf/2025/">GraphQLConf</a><a class="_text-sm contrast-more:_text-gray-700 contrast-more:dark:_text-gray-100 max-md:_hidden _whitespace-nowrap _text-gray-600 hover:_text-gray-800 dark:_text-gray-400 dark:hover:_text-gray-200" aria-current="false" href="/graphql-js/">GraphQL.JS Tutorial</a><div class="nextra-search _relative md:_w-64 max-md:_hidden"><div class="_relative _flex _items-center _text-gray-900 contrast-more:_text-gray-800 dark:_text-gray-300 contrast-more:dark:_text-gray-300"><input spellcheck="false" class="_w-full _appearance-none _rounded-lg _px-3 _py-2 _transition-colors _text-base _leading-tight md:_text-sm _bg-black/[.05] dark:_bg-gray-50/10 focus:!_bg-transparent placeholder:_text-gray-500 dark:placeholder:_text-gray-400 contrast-more:_border contrast-more:_border-current" type="search" placeholder="Search…" value=""/></div></div><button title="Change theme" class="_h-7 _rounded-md _px-2 _text-left _text-xs _font-medium _text-gray-600 _transition-colors dark:_text-gray-400 hover:_bg-gray-100 hover:_text-gray-900 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 [&_span]:hidden" id="headlessui-listbox-button-:R5l56:" type="button" aria-haspopup="listbox" aria-expanded="false" data-headlessui-state=""><div class="_flex _items-center _gap-2 _capitalize"><svg fill="none" viewBox="3 3 18 18" width="12" height="12" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" fill="currentColor" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path></svg><span class="md:_hidden">Light</span></div></button><button type="button" aria-label="Menu" class="nextra-hamburger _rounded active:_bg-gray-400/20 md:_hidden"><svg fill="none" width="24" height="24" viewBox="0 0 24 24" stroke="currentColor" class=""><g><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16"></path></g><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 12h16"></path><g><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 18h16"></path></g></svg></button></nav></div><div class="_mx-auto _flex _max-w-[90rem]"><div class="motion-reduce:_transition-none [transition:background-color_1.5s_ease] _bg-transparent"></div><aside class="nextra-sidebar-container _flex _flex-col md:_top-16 md:_shrink-0 motion-reduce:_transform-none _transform-gpu _transition-all _ease-in-out print:_hidden md:_w-64 md:_sticky md:_self-start max-md:[transform:translate3d(0,-100%,0)]"><div class="_px-4 _pt-4 md:_hidden"><div class="nextra-search _relative md:_w-64"><div class="_relative _flex _items-center _text-gray-900 contrast-more:_text-gray-800 dark:_text-gray-300 contrast-more:dark:_text-gray-300"><input spellcheck="false" class="_w-full _appearance-none _rounded-lg _px-3 _py-2 _transition-colors _text-base _leading-tight md:_text-sm _bg-black/[.05] dark:_bg-gray-50/10 focus:!_bg-transparent placeholder:_text-gray-500 dark:placeholder:_text-gray-400 contrast-more:_border contrast-more:_border-current" type="search" placeholder="Search…" value=""/></div></div></div><div class="_overflow-y-auto _overflow-x-hidden _p-4 _grow md:_h-[calc(100vh-var(--nextra-navbar-height)-var(--nextra-menu-height))] nextra-scrollbar"><div class="_transform-gpu _overflow-hidden _transition-all _ease-in-out motion-reduce:_transition-none"><div class="_transition-opacity _duration-500 _ease-in-out motion-reduce:_transition-none _opacity-100"><ul class="_flex _flex-col _gap-1 nextra-menu-desktop max-md:_hidden"><li class="[word-break:break-word] [&:not(:first-child)]:_mt-5 _mb-2 _px-2 _py-1.5 _text-sm _font-semibold _text-gray-900 dark:_text-gray-100">Learn</li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/">Introduction</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/schema/">Schemas and Types</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/queries/">Queries</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/mutations/">Mutations</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/subscriptions/">Subscriptions</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/validation/">Validation</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/execution/">Execution</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/response/">Response</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/introspection/">Introspection</a></li><li class="[word-break:break-word] [&:not(:first-child)]:_mt-5 _mb-2 _px-2 _py-1.5 _text-sm _font-semibold _text-gray-900 dark:_text-gray-100">Best Practices</li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/best-practices/">Best Practices</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/thinking-in-graphs/">Thinking in Graphs</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/serving-over-http/">Serving over HTTP</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/authorization/">Authorization</a></li><li class="_flex _flex-col _gap-1 active"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _bg-primary-100 _font-semibold _text-primary-800 dark:_bg-primary-400/10 dark:_text-primary-600 contrast-more:_border-primary-500 contrast-more:dark:_border-primary-500" href="/learn/pagination/">Pagination</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/schema-design/">Schema Design</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/global-object-identification/">Global Object Identification</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/caching/">Caching</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/performance/">Performance</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/security/">Security</a></li><li class="_flex _flex-col _gap-1"><a class="_flex _rounded _px-2 _py-1.5 _text-sm _transition-colors [word-break:break-word] _cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] contrast-more:_border _text-gray-500 hover:_bg-gray-100 hover:_text-gray-900 dark:_text-neutral-400 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50 contrast-more:_text-gray-900 contrast-more:dark:_text-gray-50 contrast-more:_border-transparent contrast-more:hover:_border-gray-900 contrast-more:dark:hover:_border-gray-50" href="/learn/federation/">Federation</a></li></ul></div></div></div><div class="nextra-sidebar-footer _sticky _bottom-0 _flex _items-center _gap-2 _mx-4 _py-4" data-toggle-animation="off"><div class="_grow _flex _flex-col"><button title="Change theme" class="_h-7 _rounded-md _px-2 _text-left _text-xs _font-medium _text-gray-600 _transition-colors dark:_text-gray-400 hover:_bg-gray-100 hover:_text-gray-900 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50" id="headlessui-listbox-button-:R2njd6:" type="button" aria-haspopup="listbox" aria-expanded="false" data-headlessui-state=""><div class="_flex _items-center _gap-2 _capitalize"><svg fill="none" viewBox="3 3 18 18" width="12" height="12" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" fill="currentColor" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path></svg><span class="">Light</span></div></button></div><button title="Hide sidebar" class="max-md:_hidden _h-7 _rounded-md _transition-colors _text-gray-600 dark:_text-gray-400 _px-2 hover:_bg-gray-100 hover:_text-gray-900 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50"><svg height="12" width="12" viewBox="0 0 16 16" fill="currentColor"><path fill-rule="evenodd" d="M4.177 7.823l2.396-2.396A.25.25 0 017 5.604v4.792a.25.25 0 01-.427.177L4.177 8.177a.25.25 0 010-.354z" class=""></path><path fill-rule="evenodd" d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0114.25 16H1.75A1.75 1.75 0 010 14.25V1.75zm1.75-.25a.25.25 0 00-.25.25v12.5c0 .138.112.25.25.25H9.5v-13H1.75zm12.5 13H11v-13h3.25a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25z"></path></svg></button></div></aside><nav class="nextra-toc _order-last max-xl:_hidden _w-64 _shrink-0 print:_hidden _px-4" aria-label="table of contents"><div class="nextra-scrollbar _sticky _top-16 _overflow-y-auto _pr-4 _pt-6 _text-sm [hyphens:auto] _max-h-[calc(100vh-var(--nextra-navbar-height)-env(safe-area-inset-bottom))] ltr:_-mr-4 rtl:_-ml-4"><p class="_mb-4 _font-semibold _tracking-tight">On This Page</p><ul><li class="_my-2 _scroll-my-6 _scroll-py-6"><a href="#plurals" class="_font-semibold _inline-block _transition-colors _subpixel-antialiased _text-gray-500 hover:_text-gray-900 dark:_text-gray-400 dark:hover:_text-gray-300 contrast-more:_text-gray-900 contrast-more:_underline contrast-more:dark:_text-gray-50 _w-full _break-words">Plurals</a></li><li class="_my-2 _scroll-my-6 _scroll-py-6"><a href="#slicing" class="_font-semibold _inline-block _transition-colors _subpixel-antialiased _text-gray-500 hover:_text-gray-900 dark:_text-gray-400 dark:hover:_text-gray-300 contrast-more:_text-gray-900 contrast-more:_underline contrast-more:dark:_text-gray-50 _w-full _break-words">Slicing</a></li><li class="_my-2 _scroll-my-6 _scroll-py-6"><a href="#pagination-and-edges" class="_font-semibold _inline-block _transition-colors _subpixel-antialiased _text-gray-500 hover:_text-gray-900 dark:_text-gray-400 dark:hover:_text-gray-300 contrast-more:_text-gray-900 contrast-more:_underline contrast-more:dark:_text-gray-50 _w-full _break-words">Pagination and edges</a></li><li class="_my-2 _scroll-my-6 _scroll-py-6"><a href="#end-of-list-counts-and-connections" class="_font-semibold _inline-block _transition-colors _subpixel-antialiased _text-gray-500 hover:_text-gray-900 dark:_text-gray-400 dark:hover:_text-gray-300 contrast-more:_text-gray-900 contrast-more:_underline contrast-more:dark:_text-gray-50 _w-full _break-words">End-of-list, counts, and connections</a></li><li class="_my-2 _scroll-my-6 _scroll-py-6"><a href="#complete-connection-model" class="_font-semibold _inline-block _transition-colors _subpixel-antialiased _text-gray-500 hover:_text-gray-900 dark:_text-gray-400 dark:hover:_text-gray-300 contrast-more:_text-gray-900 contrast-more:_underline contrast-more:dark:_text-gray-50 _w-full _break-words">Complete connection model</a></li><li class="_my-2 _scroll-my-6 _scroll-py-6"><a href="#connection-specification" class="_font-semibold _inline-block _transition-colors _subpixel-antialiased _text-gray-500 hover:_text-gray-900 dark:_text-gray-400 dark:hover:_text-gray-300 contrast-more:_text-gray-900 contrast-more:_underline contrast-more:dark:_text-gray-50 _w-full _break-words">Connection specification</a></li><li class="_my-2 _scroll-my-6 _scroll-py-6"><a href="#recap" class="_font-semibold _inline-block _transition-colors _subpixel-antialiased _text-gray-500 hover:_text-gray-900 dark:_text-gray-400 dark:hover:_text-gray-300 contrast-more:_text-gray-900 contrast-more:_underline contrast-more:dark:_text-gray-50 _w-full _break-words">Recap</a></li></ul><div class="nextra-toc-footer _mt-8 _pt-8 _sticky _bottom-0 _flex _flex-col _items-start _gap-2 _pb-8"><a href="https://github.com/graphql/graphql.github.io/issues/new?title=Feedback%20for%20%E2%80%9CPagination%E2%80%9D&labels=feedback" target="_blank" rel="noreferrer" class="_text-xs _font-medium _text-gray-500 hover:_text-gray-900 dark:_text-gray-400 dark:hover:_text-gray-100 contrast-more:_text-gray-800 contrast-more:dark:_text-gray-50">Question? Give us feedback →</a><a class="_text-xs _font-medium _text-gray-500 hover:_text-gray-900 dark:_text-gray-400 dark:hover:_text-gray-100 contrast-more:_text-gray-800 contrast-more:dark:_text-gray-50" href="https://github.com/graphql/graphql.github.io/tree/source/src/pages/learn/pagination.mdx">Edit this page</a><button aria-hidden="true" disabled="" class="_flex _items-center _gap-1.5 _transition _opacity-100 disabled:_opacity-0 _text-xs _font-medium _text-gray-500 hover:_text-gray-900 dark:_text-gray-400 dark:hover:_text-gray-100 contrast-more:_text-gray-800 contrast-more:dark:_text-gray-50">Scroll to top<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="_-rotate-90 _size-4 _border _rounded-full _border-current"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg></button></div></div></nav><div id="reach-skip-nav"></div><article class="_w-full _break-words nextra-content _flex _min-h-[calc(100vh-var(--nextra-navbar-height))] _min-w-0 _justify-center _pb-8 _pr-[calc(env(safe-area-inset-right)-1.5rem)]"><main class="_w-full _min-w-0 _max-w-6xl _px-6 _pt-4 md:_px-12"><div class="nextra-breadcrumb _mt-1.5 _flex _items-center _gap-1 _overflow-hidden _text-sm _text-gray-500 dark:_text-gray-400 contrast-more:_text-current"><div class="_whitespace-nowrap _transition-colors _min-w-[24px] _overflow-hidden _text-ellipsis" title="Learn">Learn</div><svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="_w-3.5 _shrink-0"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg><div class="_whitespace-nowrap _transition-colors _font-medium _text-gray-700 contrast-more:_font-bold contrast-more:_text-current dark:_text-gray-100 contrast-more:dark:_text-current" title="Pagination">Pagination</div></div><h1 class="_mt-2 _text-4xl _font-bold _tracking-tight _text-slate-900 dark:_text-slate-100">Pagination</h1> <p class="learn-subtitle">Traverse lists of objects with a consistent field pagination model</p> <p class="[&:not(:first-child)]:_mt-6 _leading-7">A common use case in GraphQL is traversing the relationship between sets of objects. There are different ways that these relationships can be exposed in GraphQL, giving a varying set of capabilities to the client developer. On this page, we’ll explore how fields may be paginated using a cursor-based connection model.</p> <h2 class="_font-semibold _tracking-tight _text-slate-900 dark:_text-slate-100 _mt-10 _border-b _pb-1 _text-3xl _border-neutral-200/70 contrast-more:_border-neutral-400 dark:_border-primary-100/10 contrast-more:dark:_border-neutral-400">Plurals<a href="#plurals" id="plurals" class="subheading-anchor" aria-label="Permalink for this section"></a></h2> <p class="[&:not(:first-child)]:_mt-6 _leading-7">The simplest way to expose a connection between objects is with a field that returns a plural <a class="_text-primary-600 _underline _decoration-from-font [text-underline-position:from-font]" href="/learn/schema/#list">List type</a>. For example, if we wanted to get a list of R2-D2’s friends, we could just ask for all of them:</p> <div class="miniGraphiQL"><div class="query-editor"><span class="editor-name rounded-tl">Operation</span></div><div class="result-window"><span class="editor-name rounded-tr">Response</span></div></div> <h2 class="_font-semibold _tracking-tight _text-slate-900 dark:_text-slate-100 _mt-10 _border-b _pb-1 _text-3xl _border-neutral-200/70 contrast-more:_border-neutral-400 dark:_border-primary-100/10 contrast-more:dark:_border-neutral-400">Slicing<a href="#slicing" id="slicing" class="subheading-anchor" aria-label="Permalink for this section"></a></h2> <p class="[&:not(:first-child)]:_mt-6 _leading-7">Quickly, though, we realize that there are additional behaviors a client might want. A client might want to be able to specify how many friends they want to fetch—maybe they only want the first two. So we’d want to expose something like this:</p> <div class="nextra-code _relative [&:not(:first-child)]:_mt-6"><pre class="_overflow-x-auto _subpixel-antialiased _text-[.9em] _bg-white dark:_bg-black _py-4 _ring-1 _ring-inset _ring-gray-300 dark:_ring-neutral-700 contrast-more:_ring-gray-900 contrast-more:dark:_ring-gray-50 contrast-more:_contrast-150 _rounded-md" tabindex="0"><code class="nextra-code" dir="ltr"><span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">query</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> hero</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> name</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> friends</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">first</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> name</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre><div class="_opacity-0 _transition [div:hover>&]:_opacity-100 focus-within:_opacity-100 _flex _gap-1 _absolute _right-4 _top-2"><button class="_transition _rounded-md _p-1.5 _border _border-gray-300 dark:_border-neutral-700 contrast-more:_border-gray-900 contrast-more:dark:_border-gray-50 md:_hidden" title="Toggle word wrap"><svg viewBox="0 0 24 24" width="24" height="24" class="_h-4 _w-auto"><path fill="currentColor" d="M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"></path></svg></button></div></div> <p class="[&:not(:first-child)]:_mt-6 _leading-7">But if we just fetched the first two, we might want to paginate through the list as well; once the client fetches the first two friends, they might want to send a second request to ask for the next two friends. How can we enable that behavior?</p> <h2 class="_font-semibold _tracking-tight _text-slate-900 dark:_text-slate-100 _mt-10 _border-b _pb-1 _text-3xl _border-neutral-200/70 contrast-more:_border-neutral-400 dark:_border-primary-100/10 contrast-more:dark:_border-neutral-400">Pagination and edges<a href="#pagination-and-edges" id="pagination-and-edges" class="subheading-anchor" aria-label="Permalink for this section"></a></h2> <p class="[&:not(:first-child)]:_mt-6 _leading-7">There are several ways we could do pagination:</p> <ul class="[:is(ol,ul)_&]:_my-3 [&:not(:first-child)]:_mt-6 _list-disc ltr:_ml-6 rtl:_mr-6"> <li class="_my-2">We could do something like <code class="nextra-code" dir="ltr">friends(first:2 offset:2)</code> to ask for the next two in the list.</li> <li class="_my-2">We could do something like <code class="nextra-code" dir="ltr">friends(first:2 after:$friendId)</code>, to ask for the next two after the last friend we fetched.</li> <li class="_my-2">We could do something like <code class="nextra-code" dir="ltr">friends(first:2 after:$friendCursor)</code>, where we get a cursor from the last item and use that to paginate.</li> </ul> <p class="[&:not(:first-child)]:_mt-6 _leading-7">The approach described in the first bullet is classic <em>offset-based pagination</em>. However, this style of pagination can have performance and security downsides, especially for larger data sets. Additionally, if new records are added to the database after the user has made a request for a page of results, then offset calculations for subsequent pages may become ambiguous.</p> <p class="[&:not(:first-child)]:_mt-6 _leading-7">In general, we’ve found that <em>cursor-based pagination</em> is the most powerful of those designed. Especially if the cursors are opaque, either offset or ID-based pagination can be implemented using cursor-based pagination (by making the cursor the offset or the ID), and using cursors gives additional flexibility if the pagination model changes in the future. As a reminder that the cursors are opaque and their format should not be relied upon, we suggest base64 encoding them.</p> <p class="[&:not(:first-child)]:_mt-6 _leading-7">But that leads us to a problem—how do we get the cursor from the object? We wouldn’t want the cursor to live on the <code class="nextra-code" dir="ltr">User</code> type; it’s a property of the connection, not of the object. So we might want to introduce a new layer of indirection; our <code class="nextra-code" dir="ltr">friends</code> field should give us a list of edges, and an edge has both a cursor and the underlying node:</p> <div class="nextra-code _relative [&:not(:first-child)]:_mt-6"><pre class="_overflow-x-auto _subpixel-antialiased _text-[.9em] _bg-white dark:_bg-black _py-4 _ring-1 _ring-inset _ring-gray-300 dark:_ring-neutral-700 contrast-more:_ring-gray-900 contrast-more:dark:_ring-gray-50 contrast-more:_contrast-150 _rounded-md" tabindex="0"><code class="nextra-code" dir="ltr"><span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">query</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> hero</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> name</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> friends</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">first</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> edges</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> node</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> name</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> cursor</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre><div class="_opacity-0 _transition [div:hover>&]:_opacity-100 focus-within:_opacity-100 _flex _gap-1 _absolute _right-4 _top-2"><button class="_transition _rounded-md _p-1.5 _border _border-gray-300 dark:_border-neutral-700 contrast-more:_border-gray-900 contrast-more:dark:_border-gray-50 md:_hidden" title="Toggle word wrap"><svg viewBox="0 0 24 24" width="24" height="24" class="_h-4 _w-auto"><path fill="currentColor" d="M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"></path></svg></button></div></div> <p class="[&:not(:first-child)]:_mt-6 _leading-7">The concept of an edge also proves useful if there is information that is specific to the edge, rather than to one of the objects. For example, if we wanted to expose “friendship time” in the API, having it live on the edge is a natural place to put it.</p> <h2 class="_font-semibold _tracking-tight _text-slate-900 dark:_text-slate-100 _mt-10 _border-b _pb-1 _text-3xl _border-neutral-200/70 contrast-more:_border-neutral-400 dark:_border-primary-100/10 contrast-more:dark:_border-neutral-400">End-of-list, counts, and connections<a href="#end-of-list-counts-and-connections" id="end-of-list-counts-and-connections" class="subheading-anchor" aria-label="Permalink for this section"></a></h2> <p class="[&:not(:first-child)]:_mt-6 _leading-7">Now we can paginate through the connection using cursors, but how do we know when we reach the end of the connection? We have to keep querying until we get an empty list back, but we’d like for the connection to tell us when we’ve reached the end so we don’t need that additional request. Similarly, what if we want additional information about the connection itself, for example, how many friends does R2-D2 have in total?</p> <p class="[&:not(:first-child)]:_mt-6 _leading-7">To solve both of these problems, our <code class="nextra-code" dir="ltr">friends</code> field can return a connection object. The connection object will be an Object type that has a field for the edges, as well as other information (like total count and information about whether a next page exists). So our final query might look more like this:</p> <div class="nextra-code _relative [&:not(:first-child)]:_mt-6"><pre class="_overflow-x-auto _subpixel-antialiased _text-[.9em] _bg-white dark:_bg-black _py-4 _ring-1 _ring-inset _ring-gray-300 dark:_ring-neutral-700 contrast-more:_ring-gray-900 contrast-more:dark:_ring-gray-50 contrast-more:_contrast-150 _rounded-md" tabindex="0"><code class="nextra-code" dir="ltr"><span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">query</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> hero</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> name</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> friends</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">first</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> totalCount</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> edges</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> node</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> name</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> cursor</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> pageInfo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> endCursor</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> hasNextPage</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> }</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre><div class="_opacity-0 _transition [div:hover>&]:_opacity-100 focus-within:_opacity-100 _flex _gap-1 _absolute _right-4 _top-2"><button class="_transition _rounded-md _p-1.5 _border _border-gray-300 dark:_border-neutral-700 contrast-more:_border-gray-900 contrast-more:dark:_border-gray-50 md:_hidden" title="Toggle word wrap"><svg viewBox="0 0 24 24" width="24" height="24" class="_h-4 _w-auto"><path fill="currentColor" d="M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"></path></svg></button></div></div> <p class="[&:not(:first-child)]:_mt-6 _leading-7">Note that we also might include <code class="nextra-code" dir="ltr">endCursor</code> and <code class="nextra-code" dir="ltr">startCursor</code> in this <code class="nextra-code" dir="ltr">PageInfo</code> object. This way, if we don’t need any of the additional information that the edge contains, we don’t need to query for the edges at all, since we got the cursors needed for pagination from <code class="nextra-code" dir="ltr">pageInfo</code>. This leads to a potential usability improvement for connections; instead of just exposing the <code class="nextra-code" dir="ltr">edges</code> list, we could also expose a dedicated list of just the nodes, to avoid a layer of indirection.</p> <h2 class="_font-semibold _tracking-tight _text-slate-900 dark:_text-slate-100 _mt-10 _border-b _pb-1 _text-3xl _border-neutral-200/70 contrast-more:_border-neutral-400 dark:_border-primary-100/10 contrast-more:dark:_border-neutral-400">Complete connection model<a href="#complete-connection-model" id="complete-connection-model" class="subheading-anchor" aria-label="Permalink for this section"></a></h2> <p class="[&:not(:first-child)]:_mt-6 _leading-7">Clearly, this is more complex than our original design of just having a plural! But by adopting this design, we’ve unlocked several capabilities for the client:</p> <ul class="[:is(ol,ul)_&]:_my-3 [&:not(:first-child)]:_mt-6 _list-disc ltr:_ml-6 rtl:_mr-6"> <li class="_my-2">The ability to paginate through the list.</li> <li class="_my-2">The ability to ask for information about the connection itself, like <code class="nextra-code" dir="ltr">totalCount</code> or <code class="nextra-code" dir="ltr">pageInfo</code>.</li> <li class="_my-2">The ability to ask for information about the edge itself, like <code class="nextra-code" dir="ltr">cursor</code> or <code class="nextra-code" dir="ltr">friendshipTime</code>.</li> <li class="_my-2">The ability to change how our backend does pagination, since the user just uses opaque cursors.</li> </ul> <p class="[&:not(:first-child)]:_mt-6 _leading-7">To see this in action, there’s an additional field in the example schema, called <code class="nextra-code" dir="ltr">friendsConnection</code>, that exposes all of these concepts:</p> <div class="nextra-code _relative [&:not(:first-child)]:_mt-6"><pre class="_overflow-x-auto _subpixel-antialiased _text-[.9em] _bg-white dark:_bg-black _py-4 _ring-1 _ring-inset _ring-gray-300 dark:_ring-neutral-700 contrast-more:_ring-gray-900 contrast-more:dark:_ring-gray-50 contrast-more:_contrast-150 _rounded-md" tabindex="0"><code class="nextra-code" dir="ltr"><span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">interface</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> Character</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> id</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">ID</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">String</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> friends</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">Character</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> friendsConnection</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">first</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">Int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">after</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">ID</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">): </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">FriendsConnection</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> appearsIn</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">Episode</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span> <span> </span> <span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">type</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> FriendsConnection</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> totalCount</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">Int</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> edges</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">FriendsEdge</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> friends</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: [</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">Character</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">]</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> pageInfo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">PageInfo</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span> <span> </span> <span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">type</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> FriendsEdge</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> cursor</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">ID</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> node</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">Character</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span> <span> </span> <span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">type</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> PageInfo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> startCursor</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">ID</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> endCursor</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">ID</span></span> <span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70"> hasNextPage</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">Boolean</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">!</span></span> <span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre><div class="_opacity-0 _transition [div:hover>&]:_opacity-100 focus-within:_opacity-100 _flex _gap-1 _absolute _right-4 _top-2"><button class="_transition _rounded-md _p-1.5 _border _border-gray-300 dark:_border-neutral-700 contrast-more:_border-gray-900 contrast-more:dark:_border-gray-50 md:_hidden" title="Toggle word wrap"><svg viewBox="0 0 24 24" width="24" height="24" class="_h-4 _w-auto"><path fill="currentColor" d="M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"></path></svg></button></div></div> <p class="[&:not(:first-child)]:_mt-6 _leading-7">You can try it out in the example query. Try removing the <code class="nextra-code" dir="ltr">after</code> argument for the <code class="nextra-code" dir="ltr">friendsConnection</code> field to see how the pagination will be affected. Also, try replacing the <code class="nextra-code" dir="ltr">edges</code> field with the helper <code class="nextra-code" dir="ltr">friends</code> field on the connection, which lets you get directly to the list of friends without the additional edge layer of indirection, when appropriate for clients:</p> <div class="miniGraphiQL"><div class="query-editor"><span class="editor-name rounded-tl">Operation</span></div><div class="result-window"><span class="editor-name rounded-tr">Response</span></div></div> <h2 class="_font-semibold _tracking-tight _text-slate-900 dark:_text-slate-100 _mt-10 _border-b _pb-1 _text-3xl _border-neutral-200/70 contrast-more:_border-neutral-400 dark:_border-primary-100/10 contrast-more:dark:_border-neutral-400">Connection specification<a href="#connection-specification" id="connection-specification" class="subheading-anchor" aria-label="Permalink for this section"></a></h2> <p class="[&:not(:first-child)]:_mt-6 _leading-7">To ensure a consistent implementation of this pattern, the Relay project has a formal <a href="https://relay.dev/graphql/connections.htm" target="_blank" rel="noreferrer" class="_text-primary-600 _underline _decoration-from-font [text-underline-position:from-font]">specification</a> you can follow for building GraphQL APIs that use a cursor-based connection pattern - whether or not use you Relay.</p> <h2 class="_font-semibold _tracking-tight _text-slate-900 dark:_text-slate-100 _mt-10 _border-b _pb-1 _text-3xl _border-neutral-200/70 contrast-more:_border-neutral-400 dark:_border-primary-100/10 contrast-more:dark:_border-neutral-400">Recap<a href="#recap" id="recap" class="subheading-anchor" aria-label="Permalink for this section"></a></h2> <p class="[&:not(:first-child)]:_mt-6 _leading-7">To recap these recommendations for paginating fields in a GraphQL schema:</p> <ul class="[:is(ol,ul)_&]:_my-3 [&:not(:first-child)]:_mt-6 _list-disc ltr:_ml-6 rtl:_mr-6"> <li class="_my-2">List fields that may return a lot of data should be paginated</li> <li class="_my-2">Cursor-based pagination provides a stable pagination model for fields in a GraphQL schema</li> <li class="_my-2">The cursor connection specification from the Relay project provides a consistent pattern for paginating the fields in a GraphQL schema</li> </ul><div class="_mt-16"></div><div class="_mb-8 _flex _items-center _border-t _pt-8 dark:_border-neutral-800 contrast-more:_border-neutral-400 dark:contrast-more:_border-neutral-400 print:_hidden"><a title="Authorization" class="_flex _max-w-[50%] _items-center _gap-1 _py-4 _text-base _font-medium _text-gray-600 _transition-colors [word-break:break-word] hover:_text-primary-600 dark:_text-gray-300 md:_text-lg ltr:_pr-4 rtl:_pl-4" href="/learn/authorization/"><svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="_inline _h-5 _shrink-0 ltr:_rotate-180"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>Authorization</a><a title="Schema Design" class="_flex _max-w-[50%] _items-center _gap-1 _py-4 _text-base _font-medium _text-gray-600 _transition-colors [word-break:break-word] hover:_text-primary-600 dark:_text-gray-300 md:_text-lg ltr:_ml-auto ltr:_pl-4 ltr:_text-right rtl:_mr-auto rtl:_pr-4 rtl:_text-left" href="/learn/schema-design/">Schema Design<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="_inline _h-5 _shrink-0 rtl:_rotate-180"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg></a></div></main></article></div><footer class="_bg-gray-100 _pb-[env(safe-area-inset-bottom)] dark:_bg-neutral-900 print:_bg-transparent"><div class="_mx-auto _flex _max-w-[90rem] _gap-2 _py-2 _px-4 _hidden"><button title="Change theme" class="_h-7 _rounded-md _px-2 _text-left _text-xs _font-medium _text-gray-600 _transition-colors dark:_text-gray-400 hover:_bg-gray-100 hover:_text-gray-900 dark:hover:_bg-primary-100/5 dark:hover:_text-gray-50" id="headlessui-listbox-button-:R2jl6:" type="button" aria-haspopup="listbox" aria-expanded="false" data-headlessui-state=""><div class="_flex _items-center _gap-2 _capitalize"><svg fill="none" viewBox="3 3 18 18" width="12" height="12" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" fill="currentColor" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path></svg><span class="">Light</span></div></button></div><hr class="dark:_border-neutral-800"/><div class="_mx-auto _flex _max-w-[90rem] _justify-center _py-12 _text-gray-600 dark:_text-gray-400 md:_justify-start _pl-[max(env(safe-area-inset-left),1.5rem)] _pr-[max(env(safe-area-inset-right),1.5rem)]"><div class="w-full"><div class="mb-24 flex flex-wrap items-start justify-between gap-10"><a class="max-lg:w-full" href="/"><svg xmlns="http://www.w3.org/2000/svg" style="fill:color(display-p3 .8824 0 .5961)" viewBox="0 0 367 100" class="nextra-logo h-8" title="GraphQL"><path fill-rule="evenodd" d="m50 6.468 37.7 21.766v43.532L50 93.532 12.3 71.766V28.234zM16.53 30.676v31.976l27.692-47.964zM50 13.14 18.078 68.43h63.844zm27.692 59.52H22.308L50 88.648zm5.778-10.008L55.778 14.688 83.47 30.676z" clip-rule="evenodd"></path><circle cx="14.41" cy="29.45" r="8.91"></circle><circle cx="14.41" cy="70.545" r="8.91"></circle><circle cx="50" cy="91.09" r="8.91"></circle><circle cx="85.585" cy="70.545" r="8.91"></circle><circle cx="85.585" cy="29.455" r="8.91"></circle><circle cx="50" cy="8.91" r="8.91"></circle><path d="M138.875 71.625q-7.812 0-12.125-4.5t-4.562-12.062q-.063-1.876-.063-5.938t.063-5.937q.25-7.563 4.562-12.063t12.125-4.5q5.313 0 8.938 2 3.624 2 5.375 4.75 1.812 2.688 1.937 4.813v.124q0 .501-.375.813-.375.313-.938.313h-1.374q-.562 0-.813-.25t-.5-1q-1.062-3.313-4.125-5.563-3-2.25-8.125-2.25-5.812 0-9.187 3.188-3.313 3.187-3.563 9.937-.062 1.875-.062 5.625t.062 5.625q.25 6.75 3.563 9.938 3.375 3.186 9.187 3.187 5.813 0 9.375-3.312 3.562-3.314 3.562-9.813v-3.187h-10.874q-.625 0-1-.376a1.58 1.58 0 0 1-.375-1.062v-.875q0-.625.375-1 .375-.437 1-.437h13.374q.688 0 1.063.374.375.376.375 1.063v5.5q0 4.999-2 8.813-2 3.811-5.812 5.937-3.813 2.125-9.063 2.125M165.941 71q-.625 0-1-.375t-.375-1V39.938q0-.625.375-1 .375-.438 1-.438h1q.625 0 1 .438.438.375.438 1v2.874q2.25-4.312 8.5-4.312h2.312q.625 0 1 .375t.375 1v.875q0 .625-.375 1t-1 .375h-2.687q-3.75 0-5.938 2.188-2.187 2.187-2.187 5.937v19.375q0 .625-.438 1-.375.375-1 .375zM194.557 71.625q-3 0-5.563-1.25T184.869 67q-1.5-2.126-1.5-4.687 0-4.125 3.313-6.75 3.374-2.625 9.062-3.376l9.875-1.374v-2.188q0-3.438-2.125-5.25-2.063-1.875-6.375-1.875-3.188 0-5.25 1.25-2 1.25-2.562 3-.25.75-.625 1.063-.313.25-.875.25h-.875q-.563 0-1-.376a1.5 1.5 0 0 1-.375-1q0-1.374 1.25-3.187 1.25-1.875 3.875-3.25t6.437-1.375q6.687 0 9.5 3.188 2.813 3.187 2.813 7.75v20.812q0 .625-.375 1-.376.375-1 .375h-1.063q-.625 0-1-.375t-.375-1v-2.937q-1.375 2.061-4.062 3.5-2.626 1.437-7 1.437m.625-3.625q4.561 0 7.5-3 2.937-3 2.937-8.625V54.25l-8.062 1.125q-5.125.687-7.75 2.375T187.182 62q0 2.875 2.375 4.438Q191.994 68 195.182 68M220.752 82.875q-.624 0-1-.375-.375-.375-.375-1V39.875q0-.625.375-1 .376-.375 1-.375h1.063q.625 0 1 .375t.375 1v2.938q3.626-4.938 10.5-4.938 6.75 0 9.937 4.313 3.25 4.25 3.438 10.5.063.624.062 2.062 0 1.437-.062 2.063-.187 6.25-3.438 10.562-3.187 4.25-9.937 4.25-6.813 0-10.5-4.937V81.5q0 .625-.375 1t-1 .375zM233.315 68q5.062 0 7.375-3.187 2.375-3.25 2.562-8.313.063-.625.063-1.75 0-5.813-2.25-9.5-2.25-3.75-7.75-3.75-4.938 0-7.438 3.313-2.5 3.25-2.687 7.687l-.063 2.438.063 2.437a12.8 12.8 0 0 0 1.187 5.125q1.125 2.375 3.375 3.938Q230.002 68 233.315 68M257.068 71q-.625 0-1-.375t-.375-1V28q0-.625.375-1t1-.375h1.063q.625 0 1 .375t.375 1v14.813q1.875-2.439 4.25-3.688 2.437-1.25 6.25-1.25 6.125 0 9.437 3.938 3.313 3.874 3.313 10.062v17.75q0 .625-.375 1t-1 .375h-1.063q-.625 0-1-.375t-.375-1V52.188q0-5.063-2.5-7.876-2.437-2.812-7.062-2.812-4.5 0-7.188 2.875-2.687 2.813-2.687 7.813v17.437q0 .625-.375 1t-1 .375zM321.682 75.063q-.938 0-2-1.438l-2.75-3.812q-3.75 1.812-8.75 1.812-16.062 0-16.5-17.25-.062-1.875-.062-5.25t.062-5.25q.25-8.5 4.625-12.875t11.875-4.375T320.057 31t4.625 12.875q.125 3.75.125 5.25t-.125 5.25q-.312 8.937-4.562 13.125l4 5.625q.187.376.187.688a1.2 1.2 0 0 1-.375.874 1.2 1.2 0 0 1-.875.376zm-13.5-7.188q5.625 0 8.938-3.375 3.375-3.437 3.625-10.437.125-3.75.125-4.938t-.125-4.937q-.25-7-3.625-10.376-3.375-3.437-8.938-3.437-5.562 0-8.937 3.438-3.375 3.375-3.625 10.374-.063 1.875-.063 4.938t.063 4.938q.25 6.999 3.562 10.437 3.375 3.375 9 3.375M336.126 71q-.625 0-1-.375t-.375-1v-41q0-.625.375-1t1-.375h1.188q.625 0 1 .375t.375 1V67.25h21.562q.688 0 1.063.375t.375 1.063v.937q0 .625-.438 1-.375.375-1 .375z"></path></svg></a><ul class="flex flex-col gap-4 text-sm max-lg:w-[46%]"><h3 class="text-lg font-bold">Learn</h3><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/learn/">Introduction to GraphQL</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/learn/best-practices/">Best Practices</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/faq/">Frequently Asked Questions</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/community/resources/training-courses/">Training Courses</a></li></ul><ul class="flex flex-col gap-4 text-sm max-lg:w-[46%]"><h3 class="text-lg font-bold">Code</h3><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="https://github.com/graphql">GitHub</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="https://spec.graphql.org">GraphQL Specification</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/code/">Libraries & Tools</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/code/?tags=services">Services & Vendors</a></li></ul><ul class="flex flex-col gap-4 text-sm max-lg:w-[46%]"><h3 class="text-lg font-bold">Community</h3><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/community/resources/official-channels/">Resources</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/community/events/">Events & Meetups</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/community/contribute/essential-links/">Contribute to GraphQL</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="https://landscape.graphql.org">Landscape</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="https://store.graphql.org">Shop</a></li></ul><ul class="flex flex-col gap-4 text-sm max-lg:w-[46%]"><h3 class="text-lg font-bold">& More</h3><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/blog/">Blog</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/foundation/">GraphQL Foundation</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/foundation/community-grant/">GraphQL Community Grant</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/brand/">Logo and Brand Guidelines</a></li><li><a class="hover:underline decoration-from-font [text-underline-position:from-font]" href="/codeofconduct/">Code of Conduct</a></li></ul></div><div class="flex flex-wrap justify-between gap-10"><p class="text-sm">Copyright © <!-- -->2025<!-- --> The GraphQL Foundation. All rights reserved.<br/>For web site terms of use, trademark policy and general project policies please see<!-- --> <a href="https://lfprojects.org" target="_blank" rel="noreferrer" class="text-primary hover:underline decoration-from-font [text-underline-position:from-font]">https://lfprojects.org</a></p><div class="flex flex-col gap-4 lg:items-end"><ul class="flex gap-5"><li><a href="https://github.com/graphql" target="_blank" rel="noreferrer" class="block transition-colors hover:text-primary"><svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 30 30" class="h-5 w-auto *:fill-current"><path fill-rule="evenodd" d="M15.1.413a14.81 14.81 0 0 0-4.684 28.862c.742.138 1.012-.32 1.012-.712 0-.35-.013-1.283-.02-2.518-4.12.893-4.99-1.987-4.99-1.987-.675-1.71-1.643-2.165-1.643-2.165-1.345-.918.1-.9.1-.9 1.488.105 2.27 1.525 2.27 1.525 1.32 2.265 3.466 1.61 4.31 1.23.133-.955.515-1.608.94-1.978-3.29-.375-6.747-1.645-6.747-7.32 0-1.615.577-2.937 1.525-3.975-.15-.372-.66-1.88.145-3.917 0 0 1.242-.4 4.075 1.517a14.3 14.3 0 0 1 3.705-.5 14.2 14.2 0 0 1 3.707.5c2.826-1.915 4.068-1.517 4.068-1.517.807 2.037.3 3.545.15 3.92.95 1.035 1.52 2.357 1.52 3.975 0 5.687-3.462 6.94-6.76 7.305.53.457 1.005 1.36 1.005 2.742 0 1.98-.02 3.575-.02 4.063 0 .395.267.857 1.02.712A14.816 14.816 0 0 0 15.101.413" clip-rule="evenodd"></path></svg></a></li><li><a href="https://discord.graphql.org" target="_blank" rel="noreferrer" class="block transition-colors hover:text-primary"><svg xmlns="http://www.w3.org/2000/svg" fill="#5865f2" viewBox="0 0 20 20" class="h-5 w-auto *:fill-current"><path d="M16.956 3.693a16.5 16.5 0 0 0-4.134-1.274 10 10 0 0 0-.526 1.072 15.8 15.8 0 0 0-4.58 0 13 13 0 0 0-.525-1.072c-1.429.239-2.82.667-4.135 1.274C.44 7.553-.269 11.323.085 15.043a16.8 16.8 0 0 0 5.065 2.536q.614-.828 1.08-1.747a10.6 10.6 0 0 1-1.708-.82 6 6 0 0 0 .415-.323c3.295 1.507 6.864 1.507 10.119 0 .141.111.272.223.414.324-.546.323-1.112.596-1.709.818a12.3 12.3 0 0 0 1.083 1.75 16.8 16.8 0 0 0 5.064-2.538c.434-4.305-.689-8.045-2.952-11.35m-10.27 9.056c-.99 0-1.8-.9-1.8-2.002s.79-2.001 1.8-2.001c1 0 1.82.9 1.798 2.002 0 1.101-.798 2-1.798 2m6.641 0c-.99 0-1.8-.9-1.8-2.002s.79-2.001 1.8-2.001c1 0 1.82.9 1.8 2.002 0 1.101-.79 2-1.8 2"></path></svg></a></li><li><a href="https://twitter.com/graphql" target="_blank" rel="noreferrer" class="block transition-colors hover:text-primary"><svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20" class="h-5 w-auto *:fill-current"><path d="m11.396 9.473 5.461-6.216h-1.293L10.82 8.654 7.034 3.257H2.666l5.726 8.161-5.726 6.518H3.96l5.006-5.7 4 5.7h4.367M4.427 4.212h1.987l9.149 12.816h-1.988"></path></svg></a></li><li><a href="http://stackoverflow.com/questions/tagged/graphql" target="_blank" rel="noreferrer" class="block transition-colors hover:text-primary"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 105 124" class="h-5 w-auto *:fill-current"><path fill="#bbb" fill-rule="evenodd" d="M88 80h11v44H0V80h11v33h77z" clip-rule="evenodd"></path><path fill="#f58025" d="m22.988 76.73 54.025 11.355 2.27-10.8-54.024-11.36zm7.149-25.869 50.046 23.308 4.662-10.009-50.047-23.308zm13.848-24.553 42.428 35.331 7.066-8.485-42.428-35.33zM71.372.192l-8.86 6.59 32.948 44.3 8.86-6.589zM22 102h55V91H22z"></path></svg></a></li></ul><a href="https://nextra.site" target="_blank" rel="noreferrer" class="flex items-center gap-2 text-xs transition-colors hover:text-primary">Powered by<!-- --> <svg viewBox="0 0 361 70" fill="currentColor" class="h-3 shrink-0"><path d="M114.913 33.2763v28.7642h-11.57V12.9496h11.059v8.3416h.575c1.129-2.7485 2.93-4.9325 5.401-6.5518 2.493-1.6193 5.572-2.429 9.237-2.429 3.388 0 6.339.7244 8.853 2.1733 2.535 1.4489 4.496 3.5476 5.88 6.2962 1.407 2.7486 2.099 6.0831 2.078 10.0035v31.2571h-11.57V32.5732c0-3.2813-.852-5.8487-2.557-7.7024-1.683-1.8537-4.016-2.7806-6.999-2.7806-2.024 0-3.824.4475-5.401 1.3424-1.556.8736-2.781 2.1413-3.676 3.8032-.873 1.662-1.31 3.6755-1.31 6.0405Zm61.407 29.723c-4.922 0-9.172-1.0227-12.752-3.0681-3.558-2.0668-6.296-4.9858-8.214-8.7572-1.917-3.7926-2.876-8.2563-2.876-13.3913 0-5.0497.959-9.4815 2.876-13.2954 1.939-3.8353 4.645-6.8182 8.118-8.9489 3.473-2.152 7.553-3.228 12.241-3.228 3.026 0 5.881.4901 8.565 1.4702 2.706.9588 5.093 2.4503 7.159 4.4744 2.088 2.0242 3.729 4.6023 4.922 7.7344 1.193 3.1108 1.79 6.8182 1.79 11.1221v3.5476h-40.238v-7.7983h29.148c-.021-2.2159-.501-4.1868-1.438-5.9126-.938-1.7472-2.248-3.1215-3.931-4.1229-1.662-1.0014-3.601-1.5021-5.817-1.5021-2.365 0-4.443.5753-6.232 1.7258-1.79 1.1293-3.186 2.6208-4.187 4.4745-.98 1.8324-1.481 3.8459-1.502 6.0405v6.8075c0 2.8551.522 5.3054 1.566 7.3508 1.044 2.0242 2.503 3.5796 4.378 4.6662 1.875 1.0654 4.07 1.598 6.584 1.598 1.683 0 3.207-.2343 4.57-.7031 1.364-.49 2.546-1.2038 3.548-2.1413 1.001-.9375 1.758-2.0987 2.269-3.4837l10.803 1.2145c-.682 2.8551-1.982 5.348-3.9 7.4787-1.896 2.1094-4.325 3.75-7.286 4.9219-2.962 1.1506-6.35 1.7258-10.164 1.7258Zm34.777-50.0497 9.908 18.1215 10.067-18.1215h12.241l-14.798 24.5455 15.054 24.5454h-12.177l-10.387-17.674-10.291 17.674h-12.273l14.957-24.5454-14.574-24.5455h12.273Zm63.878 0v8.9489h-28.221v-8.9489h28.221ZM253.722 1.18825h11.569V47.2749c0 1.5554.235 2.7486.704 3.5795.49.8097 1.129 1.3637 1.917 1.662s1.662.4474 2.621.4474c.724 0 1.385-.0532 1.981-.1598.618-.1065 1.087-.2024 1.407-.2876l1.949 9.0447c-.618.2131-1.502.4475-2.652.7031-1.13.2557-2.515.4049-4.155.4475-2.898.0852-5.508-.3516-7.831-1.3104-2.322-.9801-4.165-2.4929-5.529-4.5383-1.342-2.0455-2.003-4.6023-1.981-7.6705V1.18825Zm29.129 60.85225V12.9496h11.218v8.1818h.512c.895-2.8338 2.429-5.0177 4.602-6.5518 2.173-1.5554 4.677-2.3331 7.511-2.3331 1.321 0 2.535.1598 3.643.4794 1.108.3196 2.088.7564 2.94 1.3104l-3.579 9.588c-.618-.2983-1.3-.5433-2.046-.7351-.745-.1917-1.587-.2876-2.524-.2876-2.003 0-3.814.4474-5.434 1.3423-1.619.8949-2.908 2.1414-3.867 3.7394-.937 1.5767-1.406 3.4091-1.406 5.4971v28.8601h-11.57Zm51.222.863c-3.856 0-7.308-.9908-10.355-2.9723-3.047-1.9816-5.454-4.858-7.223-8.6293-1.768-3.7713-2.652-8.3523-2.652-13.7429 0-5.4546.894-10.0568 2.684-13.8068 1.811-3.7713 4.251-6.6158 7.319-8.5334 3.068-1.9389 6.488-2.9084 10.259-2.9084 2.877 0 5.242.4901 7.095 1.4702 1.854.9588 3.324 2.12 4.411 3.4836 1.087 1.3424 1.928 2.6101 2.525 3.8033h.479v-8.1179h11.602v49.0909h-11.378v-7.7343h-.703c-.597 1.1931-1.46 2.4609-2.589 3.8032-1.129 1.321-2.621 2.4503-4.474 3.3878-1.854.9375-4.187 1.4063-7 1.4063Zm3.228-9.4922c2.451 0 4.539-.6605 6.265-1.9816 1.725-1.3423 3.036-3.2066 3.931-5.593s1.342-5.1669 1.342-8.3416c0-3.1747-.447-5.934-1.342-8.2777-.874-2.3438-2.174-4.1655-3.9-5.4652-1.704-1.2997-3.803-1.9496-6.296-1.9496-2.578 0-4.73.6712-6.456 2.0135s-3.025 3.196-3.899 5.5611c-.873 2.365-1.31 5.071-1.31 8.1179 0 3.0682.437 5.8061 1.31 8.2138.895 2.3863 2.205 4.272 3.931 5.6569 1.747 1.3636 3.889 2.0455 6.424 2.0455Z"></path><path d="m64.8833 1.81335-2.8464 2.84638C47.1274 19.5692 22.9543 19.5692 8.04485 4.65972L5.19848 1.81335c-.93479-.93478-2.45037-.93478-3.38515 0-.93479.93478-.93478 2.45037 0 3.38515L4.6597 8.04487c14.9095 14.90953 14.9095 39.08263 0 53.99213l-2.84637 2.8463c-.93479.9348-.93479 2.4504 0 3.3852.93478.9348 2.45037.9348 3.38515 0l2.84637-2.8464c14.90955-14.9095 39.08255-14.9095 53.99205 0l2.8464 2.8464c.9348.9348 2.4504.9348 3.3852 0 .9347-.9348.9347-2.4504 0-3.3852l-2.8464-2.8463c-14.9095-14.9095-14.9095-39.0826 0-53.99213l2.8464-2.84637c.9347-.93478.9347-2.45037 0-3.38515-.9348-.93478-2.4504-.93478-3.3852 0Z" stroke="currentColor" stroke-width="2"></path></svg></a></div></div></div></div></footer></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/learn/pagination","query":{},"buildId":"4210ra6FRMb7c70R92Jlt","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>