<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Graphile - Medium]]></title>
        <description><![CDATA[News and information about PostGraphile and Graphile Engine - Medium]]></description>
        <link>https://medium.com/graphile?source=rss----907daaddfec9---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Graphile - Medium</title>
            <link>https://medium.com/graphile?source=rss----907daaddfec9---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 00:41:59 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/graphile" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[How I Made PostGraphile Faster Than Prisma: 1 Year Later]]></title>
            <link>https://medium.com/graphile/how-i-made-postgraphile-faster-than-prisma-1-year-later-e6bf3a802f58?source=rss----907daaddfec9---4</link>
            <guid isPermaLink="false">https://medium.com/p/e6bf3a802f58</guid>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[postgraphile]]></category>
            <category><![CDATA[graphql]]></category>
            <category><![CDATA[nodejs]]></category>
            <dc:creator><![CDATA[Benjie Gillam]]></dc:creator>
            <pubDate>Fri, 17 May 2019 14:41:10 GMT</pubDate>
            <atom:updated>2019-05-17T14:53:12.851Z</atom:updated>
            <content:encoded><![CDATA[<h4>Thanks, in part, to the incredible performance increases in Node 12</h4><p>In May last year I released <a href="https://medium.com/graphile/how-i-made-postgraphile-faster-than-prisma-graphql-server-in-8-hours-e66b4c511160">How I Made PostGraphile Faster Than Prisma In 8 Hours</a> to debunk the extremely misleading graph Prisma had integrated into their marketing website.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*76JKfxlp6dA-LkTVuk94Wg.gif" /><figcaption>I wish I had the budget to debunk this chart with equivalent pretty design and animation.</figcaption></figure><p>PostGraphile focusses on performance for the kind of GraphQL queries you’d see when building a web application following best practices—single GraphQL queries that pull all the required data for an individual web page. Prisma benchmarked an unrealistically small query (byArtistId, see below), which effectively meant they were benchmarking the HTTP layer rather than the GraphQL resolution itself. A little friendly competition is good for the ecosystem, and I hadn’t yet optimised the HTTP layer in PostGraphile, so this was good justification to set aside a day later that week to doing some performance work. It didn’t take long for PostGraphile to beat Prisma even at this trivially small query—I do love optimisation!</p><h3>Benjie 🐘 on Twitter</h3><p>So we&#39;re playing the synthetic benchmarks game are we? 😈😁</p><p>Six months later, Prisma let me know they’d taken the graph down, and had improved their own performance significantly. They requested that I re-run the benchmarks. As a <a href="https://www.graphile.org/sponsor/">crowd-funded open source developer</a>, it took a while to find more time to allocate to performance and benchmarking work.</p><p>Following <a href="https://www.graphile.org/news/postgraphile-version-4-4/">the release of PostGraphile 4.4</a>, and as a celebration of the release of Node 12, I allowed myself to spend some time deep in the developer tools for Node, finding where our performance could be further improved. chrome://inspect is incredibly useful for this purpose.</p><p>Node 12 itself brought some impressive performance gains, and it also opened wider support for modern JavaScript features, allowing us to tell TypeScript to compile to a newer ECMAScript target and leverage various performance increases from not having to poly-fill expressive syntax. To maintain backwards compatibility, these optimisations are opt-in via the GRAPHILE_TURBO environmental variable. Node 12 also brought with it a new HTTP parser, llhttp, which apparently is a little faster also. All in all, this gave us some great performance gains just from changing some compiler flags and using a newer Node.js version!</p><p>In PostGraphile’s codebase itself, there were a few places that we managed to squeeze out some more performance. I’ll release a post soon for Node.js developers explaining exactly what we did (<a href="http://eepurl.com/gfV9LD">sign up to our mailing list</a> to be notified about this and other Graphile news), but the main things were to reduce our code’s garbage collection overhead, perform more ahead-of-time computation, and to automatically track and reuse PostgreSQL prepared statements.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_9X9v7gVE4xVc0lEZZdJ4w.png" /><figcaption>From ~6:28:33 to ~6:30:18 we ran 200,000 requests against an instrumented instance of PostGraphile, and tracked the memory usage using <a href="https://github.com/nearform/node-clinic">node-clinic</a> (which is pretty cool, by the way). This “saw tooth” graph shows where Node periodically runs garbage collection (GC) to free up memory that’s no longer in use.</figcaption></figure><p>Following these optimisations I re-ran the benchmarks, testing the latest version of Prisma (1.32), PostGraphile 4.0.0 running on Node 10, and the alpha of PostGraphile 4.4.1 running on Node 12 with GRAPHILE_TURBO enabled. The only significant change we made to the benchmarks was to reduce the warmup concurrency (see albums_tracks_genre_all below for reasoning).</p><p><strong><em>Enough with the story — show us the numbers!</em></strong></p><p>In <a href="https://graphql-bench-visualizer.now.sh/">last year’s graphs</a>, the latest version of PostGraphile (labelled postgraphile-next, which was actually <a href="https://github.com/graphile/postgraphile/releases/tag/v4.0.0-beta.10">v4.0.0-beta.10</a>) was in pink. PostGraphile v4.0.0 had a similar performance profile to this version, so we’ve made that pink in <a href="https://graphql-bench-visualizer2.now.sh/">the new graphs</a> for reference. We’ve added a new line, in green, for the latest version:postgraphile@alpha (v4.4.1-alpha.4).</p><p>I also added crosses to the latency charts to indicate when 0.1% or more of the requests failed (and have labelled the crosses with the percentage of failed requests) because this is an important metric that wasn’t previously visible without cross-referencing the relevant “Successful requests” chart. Further, the Y axis has been extended to show a slightly higher range of latencies.</p><p>What follows is a section for each of the 5 queries benchmarked. The benchmark setup is almost exactly the same as last year, so I won’t go into it again (see the “Benchmarking” section from <a href="https://medium.com/graphile/how-i-made-postgraphile-faster-than-prisma-graphql-server-in-8-hours-e66b4c511160">last year’s post</a>).</p><h4>prisma_deeplyNested</h4><p>This query shows how the various softwares handle a query that touches a number of database tables, relations and columns. Prisma named this request “deeply nested” but it’s not uncommon for a frontend-facing GraphQL API to have to handle a query similar to this.</p><pre>query prisma_deeplyNested {<br>  allAlbumsList(condition: {artistId: 127}) {<br>    albumId<br>    title<br>    tracksByAlbumIdList {<br>      trackId<br>      name<br>      genreByGenreId { name }<br>    }<br>    artistByArtistId {<br>      albumsByArtistIdList {<br>        tracksByAlbumIdList {<br>          mediaTypeByMediaTypeId { name }<br>          genreByGenreId { name }<br>        }<br>      }<br>    }<br>  }<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dh9ctpTH1022sFV9mo_kTQ.png" /><figcaption>This chart shows how many requests per second the various softwares can handle before they start dropping requests (or not meeting the 5s latency cut-off). Prisma have gone from 100rps last year to 225rps — a significant increase. PostGraphile handles higher loads more gracefully now—though we start dropping requests a little after 700rps, even at 800rps we’re only dropping 2.26%.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HGY9xIF7CMiK6LuyuvdCaA.png" /><figcaption>This 95th percentile latency chart shows how quickly the various softwares respond to requests under different loads. The latest PostGraphile has reduced latency across the board, and still performs well past its peak of 600rps.</figcaption></figure><h4>albums_tracks_genre_all</h4><p>Last year we had to exclude this query as we didn’t get any results from Prisma and weren’t sure why. This year we figured it out: Prisma had become overwhelmed during the warmup period and could not respond when the main benchmarks started. The solution was to reduce the concurrency during the 5 minute warmup period from 100rps to 10rps (you can read about why warmup is necessary in last year’s post).</p><p>This query shows fetching all the rows from a particular collection in the database, and some of the related records. Typically a frontend GraphQL request like this should have pagination at the root level (e.g. limiting to 50 albums at a time), but since there’s only 347 rows in the albums table it’s not too bad. This query better represents a GraphQL query you might make from your backend rather than one from your web frontend.</p><pre>query albums_tracks_genre_all {<br>  allAlbumsList {<br>    albumId<br>    title<br>    tracksByAlbumIdList {<br>      trackId<br>      name<br>      genreByGenreId {<br>        name<br>      }<br>    }<br>  }<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*45qr_07uLx0Lh30H5_oLqw.png" /><figcaption>PostGraphile improves from 70rps to 80rps without dropping any requests.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sgxO-1uwEz_gT41NRvJ80Q.png" /><figcaption>Even at 80rps, PostGraphile handles 95% of requests in under 250ms. The latest postgraphile@alpha shows a significant reduction in latency and increase in throughput.</figcaption></figure><h4>albums_tracks_genre_some</h4><p>This query is almost identical to the previous one, except it reduces the number of results (from 347 down to just 3) by filtering against a specific artist. This is a reasonably good example of a simple frontend GraphQL query.</p><pre>query albums_tracks_genre_some {<br>  allAlbumsList(condition: {artistId: 127}) {<br>    artistId<br>    title<br>    tracksByAlbumIdList {<br>      trackId<br>      name<br>      genreByGenreId {<br>        name<br>      }<br>    }<br>  }<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9CxFtr7uAnTpUvCebbQLVA.png" /><figcaption>Prisma improved significantly—from 300rps last year to 800rps this year. PostGraphile increased from 1500rps to 1700rps, and handles going over its maximum more gracefully: at 1800rps PostGraphile drops only 0.7% of incoming requests.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*u8PkEUamk2W8NMdyDJwIzA.png" /><figcaption>PostGraphile’s latency is lower than ever, serving 95% of requests at 1700rps in under 50ms.</figcaption></figure><h4>byArtistId</h4><p>This query is extremely simple and light, just requesting two fields from a single row in the database. It’s rare that you’d have a GraphQL request this simple in the web frontend of a non-trivial application—it shows more about the underlying performance of the HTTP layer than the GraphQL resolution itself.</p><pre>query artistByArtistId {<br>  artistByArtistId(artistId: 3) {<br>    artistId<br>    name<br>  }<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CKYkQOZBW70bIykHBZ5XdA.png" /><figcaption>This graph looks surprisingly similar to last years, except everything has moved to the right! PostGraphile can now handle an impressive 3700rps (vs last year’s 3000rps) without dropping any requests, and gets to 4000rps (vs last years 3200rps) whilst dropping only 0.8% of requests. Prisma have improved too, from 2750rps without dropping a request to 3600rps.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bdcELRwDlwKNCKK7z-VkrQ.png" /><figcaption>The crosses indicating failure percentages really help to interpret the latency results here; after 3000rps Prisma manages to achieve marginally lower latency than PostGraphile for a short while until they start dropping requests at 3700rps. This is likely due to the differences in how Scala (which runs on the JVM) and Node.js handle garbage collection.</figcaption></figure><h4>tracks_media_first_20</h4><p>Included for completeness, this query requests 2 columns from 20 rows in a single database table—like a slightly heavier version of byArtistId. GraphQL requests from webpages are rarely this simple.</p><pre>query tracks_media_first_20 {<br>  allTracksList(first: 20) {<br>    trackId<br>    name<br>  }<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TmbzqmEMGPA70hNfpOZE5A.png" /><figcaption>Prisma have improved from 2000rps last year to 3000rps this year. PostGraphile increases its lead at 3500rps.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7QYJGve5avklI-ERFyH5mA.png" /><figcaption>Again, this graph shows the difference in garbage collection, HTTP overhead, and other related costs in Node.js vs Scala, with Node achieving greater throughput but with marginally higher latency at high concurrency.</figcaption></figure><h4>Is speed really that important?</h4><p>Yes and no. I do optimisations because it’s a fun challenge to see how far I can push the computer in an interpreted language without having to make my code too messy. PostGraphile’s users will now benefit from faster performance and happier endusers just from updating to the latest version — they don’t need to change any of their code at all. I think that’s really cool ✨</p><p>But performance isn’t everything—one of the things we focus on at PostGraphile is extensibility. Our job isn’t to simply convert your database from SQL to GraphQL. Our job is to help you build your ideal GraphQL API as quickly as possible. To help with that, we do as much of the boilerplate for you as we can, but then we give you ways to add to, customise and otherwise make the GraphQL schema your own. We fundamentally do not believe that our job is to expose all the functionality of the database to your end users; instead we believe that we should allow you to leverage the functionality of the database to build the GraphQL API that your frontend developers need, without them having to worry about the complexities of joins, subqueries, common-table expressions, ON CONFLICT DO UPDATE, indexes, SQL query optimisation, and other such things. Despite PostGraphile’s extensibility and flexibility it achieves incredibly good performance, thanks in part to the choice of Node.js as the development platform.</p><h4>So what’s next?</h4><p>You can take the new PostGraphile for a spin right now with yarn install postgraphile@alpha. It passes all the tests, but hasn’t been fully vetted by the community yet, hence the “alpha” label—if you try it out, drop us a line <a href="http://discord.gg/graphile">on our Discord chat</a> to let us know how you got on!</p><blockquote>yarn install postgraphile@alpha</blockquote><p>If you appreciate our work, please <a href="https://www.graphile.org/sponsor/">sponsor us</a>—we’re hugely thankful to our Patreon sponsors who help us to keep moving things forward.</p><blockquote>If you appreciate our work, please <a href="https://www.graphile.org/sponsor/">sponsor us</a>.</blockquote><p>Thanks for reading, I’ll be releasing another post soon on the Node.js performance optimisations that I used to make this possible—<a href="http://eepurl.com/gfV9LD">sign up to our mailing list</a> to be notified about this and other Graphile news.</p><blockquote><a href="http://eepurl.com/gfV9LD">Sign up to our mailing list</a>.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e6bf3a802f58" width="1" height="1" alt=""><hr><p><a href="https://medium.com/graphile/how-i-made-postgraphile-faster-than-prisma-1-year-later-e6bf3a802f58">How I Made PostGraphile Faster Than Prisma: 1 Year Later</a> was originally published in <a href="https://medium.com/graphile">Graphile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Birthday Week: Looking to the future]]></title>
            <link>https://medium.com/graphile/birthday-week-looking-to-the-future-3c0fa0cf51d2?source=rss----907daaddfec9---4</link>
            <guid isPermaLink="false">https://medium.com/p/3c0fa0cf51d2</guid>
            <category><![CDATA[postgraphile]]></category>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[graphql]]></category>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[future]]></category>
            <dc:creator><![CDATA[Benjie Gillam]]></dc:creator>
            <pubDate>Fri, 01 Feb 2019 17:32:53 GMT</pubDate>
            <atom:updated>2019-02-01T17:32:40.832Z</atom:updated>
            <content:encoded><![CDATA[<p><em>This week we’re celebrating the 1 year anniversary of our incorporation; each day we’re celebrating something, culminating with having a PostGraphile stall at FOSDEM in Brussels on Saturday and Sunday — do swing by if you’re in the area!</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*PsdnQaLZ7cjivHZT" /></figure><p><strong>PostGraphile is now in production use by many companies, with applications in industries ranging from farming to aerospace.</strong> We’ve always had a strong focus on stability, and we do our utmost to ensure you don’t have to rewrite your stack as we introduce new features (assuming you stick to the official releases!)</p><p>One of the biggest aims for the release of version 4 was to maintain as much compatibility with version 3 as we possibly could whilst <a href="https://www.graphile.org/news/postgraphile-version-4/">completely re-writing the core engine</a>, and we were very successful at this. Another big aim was to stop trying to be a “one size fits all” GraphQL solution and instead focus on handling the repetitive tasks and allowing users to customise and extend the resulting schema as they saw fit.<strong> Our plugin system has been very successful at this and is proving very powerful</strong>, with <a href="https://www.graphile.org/postgraphile/community-plugins/">community members making available a number of plugins</a> that enhance PostGraphile, and businesses writing their own private plugins to handle their own specific needs.</p><p>With all these people relying on us, it’s critical that we balance the needs to improve PostGraphile with the needs to remain stable for our users, and I think we’ve done a great job of this since the release of v4.0.0. However, many of the great improvements we’ve made since the launch of v4 are not available to users by default — they have to “opt in” via flags or plugins — and many don’t get that far in our documentation.</p><p>With that in mind, the next major version of PostGraphile, v5, will aim to improve the out-of-the-box experience, whilst making the upgrade from v4 as painless as possible for existing users via the addition of a v4 compatibility plugin.</p><p>Below, you’ll find in detail a list of most of the planned breaking changes, but in summary:</p><p>Changes which (probably) won’t have backwards compatible solutions include:-</p><ul><li>Overhauling the introspection system (only affects plugin authors)</li><li>Introducing plugin priorities (only affects plugin authors)</li><li>Type generation during `build` will be banned (only affects a small number of plugin authors)</li><li>Postgraphilerc will be changed to use library options (affects people using a postgraphilerc file)</li></ul><p>The other planned changes will probably be solvable by using a — v4 flag or similar to revert to the previous behaviour. These changes include:</p><ul><li>Simpler generated names</li><li>Will mount to the root path (“/”) by default in CLI</li><li>GraphQL schema will be responsible for managing PostgreSQL connections/transactions</li><li>NodeIDs will use GraphQL type names rather than database table names</li><li>`pgSettings` will be upgraded to deal with JWTs</li><li>`postgraphile` CLI will use first available port if port 5000 is busy</li></ul><p>More detail on these changes can be read in detail below at your leisure, and they’re still in the planning stages so do come chat with us <a href="http://discord.gg/graphile">on Discord</a> if you have any thoughts!</p><p>And so we come to the end of our Birthday Week celebrations. We have released a Medium article every day this week to celebrate, with a different focus each day. You can see them all in our new <a href="https://medium.com/graphile">Graphile Medium Publication</a>. We’ve had a fantastic time this past year, growing both PostGraphile the project and PostGraphile the community. I’m now pressing publish just as I am waiting for my plane to depart to Brussels for FOSDEM (so excuse typos!) and, as always, want to take this opportunity to send a HUGE THANK YOU to all our sponsors, contributors, evangelists and other supporters — this would not be possible without you!</p><p>Remember, if you don’t already, you can <a href="https://patreon.com/benjie">sponsor PostGraphile on Patreon</a>, and <a href="http://discord.gg/graphile">join our community on Discord</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Ft39zkQ9NWouhTDk" /></figure><h3>Backwards Incompatible Breaking Changes</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*nld1xig7KmMW-j2x" /></figure><h4><strong>Introspection</strong></h4><p>We’ll be changing the introspection system to be extensible via plugins; we’ll also probably switch to getter methods for retrieving things rather than (or in addition to) object traversal. A hook will probably be added to enable you to augment introspection results before they are “baked” (interlinked/cached/etc).</p><h4><strong>Hook priorities</strong></h4><p>Hooks will define priorities (or provides/depends — it’s not been decided yet) that allow you to control the order in which they are applied without the user having to reference plugins in a particular order.</p><h4><strong>Type generation during `build` will be banned</strong></h4><p>And type generation during `init` will be dissuaded. Sadly, I learned that building types during `build` was not optimal only after the release of 4.0.0. The issue is that it makes it a lot harder for other plugins to hook these objects since the build object may not be finalised (so not all the helpers are present yet). It can also result in building “orphaned” objects that are never used, wasting processing time and memory. In v5 we’ll probably switch to registering type generator functions that are executed “Just In Time” rather than generating types up front (we already do this with table, view and compound types and it works brilliantly).</p><h4><strong>Postgraphilerc will be changed to use library options</strong></h4><p>Currently postgraphilerc uses the options that come out of the CLI library that we use, which do not always use the names documented in the CLI or Library pages. We’ll change it so that it uses the library option names instead. This should also mean that a postgraphilerc could be shared between library and CLI usage which would be awesome!</p><h4><strong>Enhanced GraphiQL will be the only GraphiQL</strong></h4><p>GraphiQL, the GraphQL IDE, is an excellent tool for exploring your GraphQL API, and with recent enhancements such as GraphQL Explorer from OneGraph it’s better than ever. Since it’s easy to add your own bespoke GraphiQL route should you so desire, we’re going to focus on PostGraphiQL (our flavour) as a development tool, and as such we’ll be changing it and enhancing it over time. You can still use it in production if you want, but it will be PostGraphile branded 😉</p><h3>Backwards Compatible Breaking Changes</h3><p>Isn’t that an oxymoron? Well, thanks to our powerful plugin system: no. We’re able to make changes to defaults and the schema in v5 whilst offering a flag/plugin that restore the behaviours of v4 that your application uses.</p><h4><strong>Simpler names by default</strong></h4><p>Anyone who has been following along with @graphile-contrib/pg-simplify-inflector will know that one of my obsessions is simplifying our generated GraphQL schemas down from having fields like `personByAuthorId` to simply `author`. It’s a challenge to do this in an auto-generated schema without causing field name conflicts, but pg-simplify-inflector has done a great job and I believe we can do even better… If we can, without causing a significant drop in compatibility with existing databases, then I definitely plan to bake this in as default behaviour in v5 (but it will be made backwards compatible via a plugin). For now, you can use @graphile-contrib/pg-simplify-inflector to get a feel for this, just beware of semver-major updates changing names of things.</p><h4><strong>Will mount to the root path (/) by default in CLI</strong></h4><p>We currently mount to /graphql and /graphiql for legacy reasons, this sometimes causes user confusion. We will change this to `/` by default for the CLI (and maybe also the library) but you can still use the relevant GraphQL route options to configure this back to its old behaviour.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*73I-sCquXod3e_WK" /></figure><h4><strong>PostgreSQL connections baked into the schema</strong></h4><p>In all previous versions of PostGraphile, when you run a query you first get a PG client from the pool, start a transaction, configure the transaction for the user, and then you pass that client to the GraphQL schema (via the `context` argument) for use during resolution. Once the GraphQL request has resolved you then commit the transaction and release the client back to the pool. This has worked really well for PostGraphile’s own server/middleware, but unfortunately it works less well with various other software in the GraphQL ecosystem that do not have support for guaranteed (and asynchronous) active releasing of the GraphQL context. This means that when you combine PostGraphile with other GraphQL tools you sometimes have to use it as a remote schema.</p><p>In version 5 we’re going to change how this behaves a little: if you pass a pgClient on `context` then all will work as before, but if you do not (which will be the default for the PostGraphile server) then the schema will manage allocating and configuring PG clients and transactions. This should greatly increase our compatibility with other GraphQL tooling such as Apollo Server and GraphQL Weaver.</p><h4><strong>Node IDs</strong></h4><p>Graphile Engine uses the GraphQL type name in the generated NodeIDs, but as part of maintaining compatibility with version 3, we had to add a plugin (PgNodeAliasPostGraphile) that overrode these NodeIDs to instead use the actual table names. This means if you base64 decode a NodeID in PostGraphile currently you can see the underlying table name (even if you’ve renamed the resource using smart comments or an inflector plugin).</p><p>Version 5 will using the Graphile Engine native NodeIDs by default, but you will be able to <a href="https://github.com/graphile/graphile-engine/blob/532fd40406a22c658f6f287b290937e81950008e/packages/graphile-build-pg/src/plugins/PgNodeAliasPostGraphile.js">add a small plugin</a> to restore the v3-flavoured NodeIDs.</p><h4><strong>pgSettings will be enhanced or replaced</strong></h4><p>We’re going to change how pgSettings interacts with JWTs slightly, and try and make it work better with other transports such as websockets. If necessary we’ll introduce a new interface, but we’re hoping to avoid this.</p><h4><strong>The CLI `postgraphile` will find first available port</strong></h4><p>If port 5000 is in use and you don’t specify a port number, we’ll find an available port. To stop this being a breaking change, ensure you explicitly set the port number on the command line: `-p 5000`</p><p>Wow, thanks for reading this far! If you have any feedback, come chat to me on Discord (but don’t expect fast responses this weekend as we’re at FOSDEM!)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3c0fa0cf51d2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/graphile/birthday-week-looking-to-the-future-3c0fa0cf51d2">Birthday Week: Looking to the future</a> was originally published in <a href="https://medium.com/graphile">Graphile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Birthday Week: Gratitude]]></title>
            <link>https://medium.com/graphile/birthday-week-gratitude-8503fbe8c8a1?source=rss----907daaddfec9---4</link>
            <guid isPermaLink="false">https://medium.com/p/8503fbe8c8a1</guid>
            <category><![CDATA[thank-you]]></category>
            <category><![CDATA[postgraphile]]></category>
            <category><![CDATA[gratitude]]></category>
            <category><![CDATA[sponsorship]]></category>
            <category><![CDATA[graphql]]></category>
            <dc:creator><![CDATA[Jem Gillam]]></dc:creator>
            <pubDate>Thu, 31 Jan 2019 19:25:03 GMT</pubDate>
            <atom:updated>2019-01-31T19:24:46.556Z</atom:updated>
            <content:encoded><![CDATA[<p><em>This week we’re celebrating the 1 year anniversary of our incorporation; each day we’re celebrating something, culminating with having a PostGraphile stall at FOSDEM in Brussels on Saturday and Sunday — do swing by if you’re in the area!</em></p><p><strong>I love hearing from PostGraphile users</strong> about how they use the software, especially when I hear stories like how <a href="https://chads.website/development/2018/08/03/How-GraphQL-Saved-My-Project.html">PostGraphile enabled two developers to do a better job in three months than 8 developers did in a year</a>. Just yesterday, user ‘@envoked’ popped into our Discord chat:</p><blockquote>I’ve been using PostGraphile to prototype a GraphQL backend at my company and I’m super impressed. It brings me the same level of joy I had when I first discovered Rails/ActiveRecord 10+ years ago. Thanks Benjie and team.</blockquote><p>This kind of feedback is only possible because we have been able to spend significant time on PostGraphile throughout the last year. Back in January 2018, we set up <a href="http://www.patreon.com/benjie">a Patreon sponsorship page</a> and began asking for contributions towards our time working on the project. By September, we passed the $1000 /mo mark and with this growing support we’ve been able to devote more and more of our time to PostGraphile.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*LZKWJA-Ut89lIkcE" /><figcaption>Patreon donations since starting the page</figcaption></figure><p>Among other things, Patreon support has enabled us to -</p><ul><li>Massively increase PostGraphile performance</li><li>Implement the powerful Smart Comments system for customising your GraphQL schema</li><li>Make PostGraphile smarter about PostgreSQL extensions, permissions and indexes</li><li>Implement `graphile-utils` — a module that makes it much easier to customise your schema</li><li>Overhaul the error system, including adding helpful hints on how to fix many issues</li><li>Enhance the plugin API to better support community plugin developers</li><li>Overhaul and massively improve our TypeScript support</li></ul><p>Besides these new features, Patreon support has also enabled us to work hard to improve PostGraphile’s documentation—we’ve even received a lot of compliments on it recently! Of course, there’s always more to do, and along with the new learning resources at <a href="https://learn.graphile.org/">learn.graphile.org</a> (see <a href="https://medium.com/graphile/birthday-week-sharing-a908052f8602">Tuesday’s post</a>) we’re going to be having a special focus on documentation and examples over the coming months.</p><h3><strong>We want to take this opportunity to say a huge “thank you!” to everyone who has donated any amount to our Patreon over the past year.</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dioW8kciVoy3HsKAulbfuw.png" /></figure><p>Since December 2017, Patreon supporters on the “Sponsor” tier or above have been listed inside the PostGraphile project in a <a href="https://github.com/graphile/postgraphile/blob/master/SPONSORS.md">“SPONSORS.md” file</a>. Back in November, we updated the PostGraphile command’s greeting message to feature a random sponsor.</p><p>Today, as part of our ongoing website overhaul, we are happy to announce we are now featuring sponsors <a href="https://www.graphile.org/sponsor/">on our website</a>. <strong>PostGraphile is a community effort</strong>, so we are pleased to underline this on our website.</p><p>We also want to extend our sincere thanks to all our GitHub contributors over the lifetime of the project. All code and documentation contributions, no matter how large or small, whether you’re a seasoned open source contributor or this is your first pull request, are all welcomed.</p><p>If you would like to get involved with contributions, <a href="http://discord.gg/graphile">pop into our Discord chat</a> and get to know our community. We are also building a thriving community of plugin authors and would love more people to come and join us to help make PostGraphile even more awesome.</p><p>If you’d like to support our work and enable us to spend more time working on PostGraphile, please visit our Patreon page at <a href="https://www.patreon.com/benjie">patreon.com/benjie</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TTd17YbpZHgW9XX74TQlkg.png" /></figure><p>Join us again tomorrow for our last post in this Birthday series, a look at what’s to come…</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8503fbe8c8a1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/graphile/birthday-week-gratitude-8503fbe8c8a1">Birthday Week: Gratitude</a> was originally published in <a href="https://medium.com/graphile">Graphile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Birthday Week: Mutual Support]]></title>
            <link>https://medium.com/graphile/birthday-week-mutual-support-2df6c71b54b0?source=rss----907daaddfec9---4</link>
            <guid isPermaLink="false">https://medium.com/p/2df6c71b54b0</guid>
            <category><![CDATA[graphql]]></category>
            <category><![CDATA[professional-services]]></category>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[postgraphile]]></category>
            <dc:creator><![CDATA[Benjie Gillam]]></dc:creator>
            <pubDate>Wed, 30 Jan 2019 19:57:45 GMT</pubDate>
            <atom:updated>2019-01-30T19:57:37.818Z</atom:updated>
            <content:encoded><![CDATA[<p><em>This week we’re celebrating the 1 year anniversary of our incorporation; each day we’re celebrating something, culminating with having a PostGraphile stall at FOSDEM in Brussels on Saturday and Sunday — do swing by if you’re in the area!</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cNOnY_NxlQPROCp6Txj4bw.png" /></figure><p><strong>I’m excited to announce PostGraphile now offers professional support contracts.</strong></p><p>We can help you get started with PostGraphile, give you tailored advice when you need it, help fix performance issues, and give priority support on any issues you face whilst using PostGraphile. And the best thing is that while we’re supporting you, you’re supporting our continued open source work on PostGraphile! You can read more about our support offering here:</p><blockquote><a href="https://www.graphile.org/support/">https://www.graphile.org/support/</a></blockquote><p>We’ve been trialing this support offering for the last couple months with the fine folks over at <a href="https://www.learnlight.com/en/">learnlight.com</a>, and <strong>in just one 30 minute phone call managed to save them days of work</strong> thanks to some significant performance optimisations to their security infrastructure. We’ve also shared relevant knowledge and experience to help the team form a bespoke set of best practices to guide their developers. Demian Martinez from Learnlight says:</p><blockquote>We manage a web platform providing language and skills learning services to over 100k users worldwide. We wanted a GraphQL API server based on a PostgreSQL backend, and to focus on writing business code instead of data mapping, conversion and plumbing.<br> <br>After almost a year of explorations and tests, we settled on PostGraphile to power our new platform. PostGraphile now replaces the entire API server and saves us from having to manually create GraphQL schemas, resolvers and connectors that add no value but take time, effort and bugs. This means faster prototyping and shorter sprints.<br> <br>Benjie provides outstanding professional support and will even develop bespoke extensions—if you are going to bet the future of your platform on PostGraphile, becoming a professional customer is the first thing you should do.</blockquote><h4>Why professional support?</h4><p>At Graphile we love open source because it means people can use our software in amazing places and interesting ways, can share their learnings with others, and can even contribute back features, fixes and documentation — it reduces the barrier to entry, and engenders trust and community.</p><p>For development on an open source project to be sustainable, there needs to be a source of income so the developers can continue to pay their mortgages, feed their kids, and once in a while take some well-earned time off. The absolute best way to support PostGraphile’s ongoing development efforts, the most bang-for-your-buck as it were, is to become a Patreon sponsor. Crowd-sourced funding enables us to spend the most time directly working on improving PostGraphile, which you and other PostGraphile users then benefit from.</p><p>Sometimes, however, you need something from us — some advice, to validate a potential bug, help figuring out how to achieve some goal — and you’ve got time pressures. This is where open source can fall down — no reasonable human would expect a stranger to help their business earn money on a tight deadline without some quid pro quo. This is where professional support comes in — it gives you guarantees that you’ll get a response to your issue in a timely fashion, and it gives us a steady income that we can rely on to dedicate more time to working on PostGraphile — mutual support.</p><p>Find out more about professional support at <a href="https://www.graphile.org/support/">graphile.org/support</a>, and join us again tomorrow for a celebration of our Patreon supporters!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fZ30bmFnEjBHYZpu4Asplg.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2df6c71b54b0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/graphile/birthday-week-mutual-support-2df6c71b54b0">Birthday Week: Mutual Support</a> was originally published in <a href="https://medium.com/graphile">Graphile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Birthday Week: Sharing]]></title>
            <link>https://medium.com/graphile/birthday-week-sharing-a908052f8602?source=rss----907daaddfec9---4</link>
            <guid isPermaLink="false">https://medium.com/p/a908052f8602</guid>
            <category><![CDATA[graphql]]></category>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[postgraphile]]></category>
            <category><![CDATA[sharing]]></category>
            <dc:creator><![CDATA[Jem Gillam]]></dc:creator>
            <pubDate>Tue, 29 Jan 2019 19:43:25 GMT</pubDate>
            <atom:updated>2019-01-29T19:56:35.537Z</atom:updated>
            <content:encoded><![CDATA[<p><em>This week we’re celebrating the 1 year anniversary of our incorporation; each day we’re celebrating something, culminating with having a PostGraphile stall at FOSDEM in Brussels on Saturday and Sunday — do swing by if you’re in the area!</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*xF4aX_sQLDYHloQc" /></figure><p>Over the last 12 months of working on Graphile, I have learned a lot about both GraphQL and the open source community as a whole. It has been an incredible experience, and I can’t wait to see what the future holds.</p><p>To begin with, my <strong>focus was on the PostGraphile documentation</strong>. Benjie and I have both spent a lot of time improving and expanding our docs, adding features such as the <a href="https://www.graphile.org/postgraphile/examples/">various galleries</a>, search, and advice sections sharing tips and best practices.</p><p>GraphQL is a fairly new technology, so it’s no surprise that a large number of people coming to PostGraphile are unfamiliar with GraphQL and are looking for a quick and easy way to get started. As time went on, we found that not only did we need good documentation about PostGraphile itself, but we also needed resources about GraphQL in general. To that end…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EAfEqjyXGaiur2rN0KpCbQ.png" /></figure><h3>We’re proud to announce the launch of our learning resources website, covering GraphQL, PostgreSQL and PostGraphile:</h3><h4><a href="https://learn.graphile.org/">https://learn.graphile.org</a></h4><p>We have three learning resources ready for download:</p><ul><li>A GraphQL Operations cheatsheet</li><li>A GraphQL Schema Language cheatsheet</li><li>A PostgreSQL Row Level Security infosheet</li></ul><p>They’re designed to be a quick reference for some of the technical language you come across when first using these technologies. There’s a nifty annotated diagram of a GraphQL query, plus there’s an entire infosheet about Row Level Security, something that is commonly misunderstood.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*m6Pl3rF9tVdcvHgzMddmNw.jpeg" /><figcaption><a href="https://learn.graphile.org/">Download the GraphQL Operations cheatsheet now</a></figcaption></figure><p>These were designed in collaboration with a local agency in Southampton, <a href="https://hinge.agency/">Hinge</a>, and we are very happy with how they’d turned out. We have had some of these professionally printed which we want to share, so we’re <a href="https://www.patreon.com/posts/postgraphile-now-24148282">sending some out this week to our Patreon Sponsors</a>.</p><p>We are also taking these and some other goodies with us to FOSDEM, Europe’s biggest open source conference. <strong>If you’re in Brussels this weekend, come and visit us in the K building</strong> at the conference. We always love sharing our love of GraphQL, we can’t wait!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/772/1*SS1Ez2oEq8mBBqvANy-HCg.png" /><figcaption>We are so excited to visit a new country and spend time in the open source community, meeting lots of new people and spreading the love of GraphQL.</figcaption></figure><p>Join us again tomorrow to find out how you can help us to help you…</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a908052f8602" width="1" height="1" alt=""><hr><p><a href="https://medium.com/graphile/birthday-week-sharing-a908052f8602">Birthday Week: Sharing</a> was originally published in <a href="https://medium.com/graphile">Graphile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Birthday Week: Doubling Down]]></title>
            <link>https://medium.com/graphile/birthday-week-doubling-down-c59b7cc72385?source=rss----907daaddfec9---4</link>
            <guid isPermaLink="false">https://medium.com/p/c59b7cc72385</guid>
            <category><![CDATA[birthday]]></category>
            <category><![CDATA[thank-you]]></category>
            <category><![CDATA[teamwork]]></category>
            <category><![CDATA[graphql]]></category>
            <category><![CDATA[postgres]]></category>
            <dc:creator><![CDATA[Benjie Gillam]]></dc:creator>
            <pubDate>Mon, 28 Jan 2019 20:02:08 GMT</pubDate>
            <atom:updated>2019-01-28T20:04:26.411Z</atom:updated>
            <content:encoded><![CDATA[<p><em>This week we’re celebrating the 1 year anniversary of our incorporation; each day we’re celebrating something, culminating with having a PostGraphile stall at FOSDEM in Brussels on Saturday and Sunday — do swing by if you’re in the area!</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*SYYUOuIOXdO7rYgF" /></figure><p>One year ago, I decided it was time to get serious about PostGraphile. Having worked on it as a side-project for over a year by that point, it was clear that to make development sustainable I’d have to find a way of earning a living from my work. <a href="http://twitter.com/jemgillam">Jem</a> and I wanted to find a stream of income which complemented my work on PostGraphile, and enabled her to become more involved.</p><p>After much thought, we went into business together, creating a software development and training company using a portmanteau of our names: Jemjie Ltd. We were quickly successful in finding related work: helping companies to build their stack around PostGraphile in an advisory and/or development role, and a stint of GraphQL training.</p><p><strong>As time went on, it became clear we couldn’t take on too much of this work or we would not have time left to work on PostGraphile itself</strong>. This is where our <a href="https://patreon.com/benjie">Patreon supporters</a> made a huge difference — by funding time for us to work directly on PostGraphile, we could take a break from the consultancy work and spend time closing issues, reviewing pull requests, writing documentation, and advancing the project with new features.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*KPKQRgWgK2E9N9UO" /></figure><p>Throughout the year, more and more community members stepped forward to help support the project financially and <strong>just last week we passed the $1500/mo goal</strong> allowing us to dedicate the equivalent of one day per week entirely to development on PostGraphile (and that’s not including the constant attention to GitHub issues and PRs, or supporting people via our Discord chat).</p><p>Another source of great support came in the form of sponsored development for specific PostGraphile features. These have included:</p><ul><li>Massively improved Lambda support thanks to <a href="https://www.graphile.org/news/postgraphile-version-4-1/">better webpackability</a>, which included decreasing bundle size by 10 times, and decreasing cold start times to under 0.5 seconds.</li><li>Enhancements to PostGraphile’s support for PostgreSQL VIEWs and MATERIALIZED VIEWs; through adding support for defining constraints (e.g. foreign keys, primary keys, not null, etc) using <a href="https://www.graphile.org/postgraphile/smart-comments/">smart comments</a></li><li>An <a href="https://github.com/graphile/operation-hooks">operation hooks</a> plugin which enables you to add additional checks and send additional metadata back to the client when you attempt mutations — e.g. custom validation messages, authorisation checks and assertions, or even warning the user their credit card is expiring soon</li></ul><p>In addition to thanking all our generous Patreon supporters, our thanks go out to CoGo, Ulta, and Learnlight for sponsoring the development of the features they needed, and then sharing these features with the community.</p><p>Thanks to all this support from PostGraphile users, we’ve been able to spend a lot more time on PostGraphile than we expected — I’m extremely proud of the advancements we’ve made, and am very excited for the future! PostGraphile is now in production use by many companies, with applications in industries ranging from farming to aerospace.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*lbjNHSdlOmJisqvf" /></figure><p>Reflecting on the successes of the past year, Jem and I are doubling down on our commitment to PostGraphile. We’re happy to announce that we’ve renamed our company to <strong>Graphile Ltd</strong> to reflect our focus, we’re only taking on PostGraphile related contracts, and we’ve got more announcements to come about how we intend to support increasing development time on PostGraphile.</p><blockquote>This would not be possible without you, PostGraphile users and supporters, so a huge thank you to you all!</blockquote><p>Join us again tomorrow for Jem on sharing our knowledge…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ZwMrl0E1ocgEhkUd" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c59b7cc72385" width="1" height="1" alt=""><hr><p><a href="https://medium.com/graphile/birthday-week-doubling-down-c59b7cc72385">Birthday Week: Doubling Down</a> was originally published in <a href="https://medium.com/graphile">Graphile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How I Made PostGraphile Faster Than Prisma GraphQL Server In 8 Hours]]></title>
            <link>https://medium.com/graphile/how-i-made-postgraphile-faster-than-prisma-graphql-server-in-8-hours-e66b4c511160?source=rss----907daaddfec9---4</link>
            <guid isPermaLink="false">https://medium.com/p/e66b4c511160</guid>
            <category><![CDATA[database]]></category>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[api]]></category>
            <category><![CDATA[graphql]]></category>
            <dc:creator><![CDATA[Benjie Gillam]]></dc:creator>
            <pubDate>Mon, 28 Jan 2019 19:04:44 GMT</pubDate>
            <atom:updated>2019-05-17T15:00:31.424Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rsRR202FXcTzxBa0GSiBGQ.png" /><figcaption>(Lower and to the right is better.) 95th precentile latency comparison of Prisma (blue), current PostGraphile (v4.0.0-beta.9, purple), and the next version of PostGraphile (postgraphile@next, pink). Prisma stays under 50ms latency up to 250 requests per second (rps); current PostGraphile reaches 900rps without breaching 50ms latency; but the next version of PostGraphile kicks the ball out of the park with an astounding 1450rps!!</figcaption></figure><p><strong><em>TL;DR: </em></strong><a href="https://www.graphile.org/postgraphile/"><strong><em>PostGraphile</em></strong></a><strong><em> was already highly performant for complex GraphQL queries, but the next release is faster still, and now it’s great at the very simple queries found in Prisma’s benchmarks too!</em></strong></p><p><strong><em>UPDATE: </em></strong><a href="https://github.com/graphile/postgraphile/releases/tag/v4.0.0-beta.10"><strong><em>postgraphile@next is now released</em></strong></a><strong><em>.</em></strong></p><p><strong><em>UPDATE 2: a year has passed, </em></strong><a href="https://medium.com/graphile/how-i-made-postgraphile-faster-than-prisma-1-year-later-e6bf3a802f58"><strong><em>see our 2019 update here</em></strong></a><strong><em>.</em></strong></p><p>As PostGraphile v4 gets towards the end of it’s beta period, the time has been coming to start thinking about performance optimisations. And as luck would have it, both Hasura and Prisma have recently released benchmarks comparing their GraphQL offerings to PostGraphile! This sudden interest in comparative benchmarking was sufficient excuse for me to dedicate some time to finding the low-hanging fruit of PostGraphile performance optimisations.</p><p>One of the main reasons behind the PostGraphile v4 rewrite was to achieve significantly greater performance than v3 (which was known as “PostGraphQL”). This has been <a href="https://github.com/graphile/postgraphile_changes/blob/master/results.md">very successful</a> for complex queries of the type that PostGraphile typically deals, where you’re requesting all the data required to render a web page in one single GraphQL query.</p><p>What I realised with the chart on Prisma’s shiny new marketing site is that their benchmark wasn’t against the large nested queries I had been focussed on optimising. Instead, they had focussed on the other end of the scale — extremely small simple queries — which makes sense given the way that they intend Prisma to be used. (PostGraphile is a front-line GraphQL server intended to serve requests direct from end clients such as web browsers, whereas Prisma is intended to be the backend to another GraphQL schema.)</p><p>Still, the performance difference for these small queries shouldn’t be as great as Prisma’s chart implied… Grateful for the wake-up call I realised it was time to look at PostGraphile’s per-request performance — how quickly could we serve trivial queries that just request a couple of fields from an individual database row like the following?</p><pre>{<br>  artistById(id: 3) {<br>    id<br>    name<br>  }<br>}</pre><p>Prisma gave me the heads up about the benchmarks the night before they launched their site (Tuesday last week), and by Friday I’d managed to allocate about 6 hours on the task and had achieved quite substantial performance gains. On Monday, whilst writing up this post, I got distracted with another performance thread and spent another couple hours on it. Here’s some of the strategies I applied to improve performance:</p><h4>Simple list-based collections</h4><p>First, I intuited that Prisma were likely benchmarking simple GraphQL lists, whereas PostGraphile only supported best-practices Relay-compatible connections (which are more expensive to execute). I’ve seen chatter here and there that people would like to see simpler collections in PostGraphile so this seemed a “two drones¹ with one stone” opportunity.</p><p>You may be happy to hear that, as a direct result of this, PostGraphile now has support for simple list-based collections as well as Relay connections! When the next release of PostGraphile goes out you’ll be able to use them with the CLI flag--simple-collection both. This will probably become the default before PostGraphile v4 is officially released.</p><p>¹<em> no birds were harmed in the writing of this post</em></p><h4>Disable expensive query logging</h4><p>Second, I realised that our logging is unnecessarily expensive — by default we print a reformatted single-line version of every single GraphQL query that comes in — great for debugging but not so good for performance benchmarks! When you use PostGraphile as an Express middleware you can turn this off via the disableQueryLog option, but there wasn’t a way to disable it on the PostGraphile CLI; until now! Just add --disable-query-log to skip logging entirely; at some point we may add more efficient and conventional logging as an option but I didn’t have time this week!</p><h4>Lighter resolution</h4><p>I took a quick scan over the most high-trafficked areas of the GraphQL schema: the resolvers. It turned out there was a couple of places where I was performing chained .filter(…) calls inside the GraphQL resolvers. A simple V8 optimisation here would have been to roll these up into a single filter call; but I realised… these don’t need to be in the resolvers at all! I moved the calculations to the parent contexts so the resolvers could use the pre-computed results and thus had less work to do.</p><h4>Optimising the HTTP layer</h4><p>Another realisation was that I’d spent much of my time optimising the actual GraphQL schema and SQL execution (through the invention of the <a href="https://www.graphile.org/graphile-build/">graphile-build</a> suite). However, the HTTP server/middleware portion of PostGraphile has barely been touched since I took over as maintainer from the ever-inspirational <a href="https://twitter.com/calebmer">Caleb</a> (who has now moved from the Flow team to the Oculus(!) team at Facebook). Well, the time had finally come! I broke out the Chrome DevTools, hooked them up to PostGraphile and got profiling.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2FxUA7ba9aksCuKR9dgA%2Ftwitter%2Fiframe&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FxUA7ba9aksCuKR9dgA%2Fgiphy.gif&amp;image=https%3A%2F%2Fi.giphy.com%2Fmedia%2FxUA7ba9aksCuKR9dgA%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="244" frameborder="0" scrolling="no"><a href="https://medium.com/media/ea69760fe748e085944eda35ba5f207a/href">https://medium.com/media/ea69760fe748e085944eda35ba5f207a/href</a></iframe><p><em>(Aside: to everyone in the Chrome, V8 and Node.js projects who have made debugging and profiling the latest versions of Node such a delight, my heartfelt thanks go out to you. These tools are incredible and it has been a joy to experience the frequent advancements over the last 5 years! Thank you so much, and keep up the great work!)</em></p><blockquote><em>Long story short, we now perform more of the computations during startup rather than at request processing time; we don’t recalculate things over and over if we can avoid it¹; we do standard V8 optimisations such as storing repeatedly referenced deep object properties to a variable to avoid re-incurring object traversal costs² and avoiding unnecessary function calls³; and we avoid fancy new things like </em><em>Map in performance-critical paths for more performant alternatives such as plain objects and arrays.</em></blockquote><p>¹ <em>no more multiple calls to </em><em>parseUrl(req) for the same request!</em><br>² <em>and making the code more readable as a bonus</em><br>³ <em>for example by turning </em><em>array.forEach(…) calls into traditional </em><em>for loops, and in certain cases moving function guards outside of the functions</em></p><h4>No unnecessary transactions</h4><p>When I first wrote this article yesterday, Prisma were still beating PostGraphile on the tiny query byArtistId, and I enumerated some reasons that might be. Then I realised that one of them was relatively easy to fix — I intuited that Prisma might not be using transactions for their queries because they don’t need to (saving them for mutations only). Turns out that PostGraphile doesn’t need transactions around queries either, <em>unless</em> it is configured to set some PostgreSQL settings e.g. via pgSettings or from a JWT or similar.</p><p>I quickly edited PostGraphile to only use transactions when it needs to, and that was sufficient for us to squeeze the last bit of performance out to beat Prisma even on the simplest queries. Seems that even the begin/commit network packets were weighing down PostGraphile’s performance, not including the additional work the database had to do to track the transaction! Fixing the tests to not expect these statements took longer than implementing the feature itself 😅</p><h4>Benchmarking</h4><p>On Thursday I asked Prisma for their test suite, and they happily provided it to me the next day along with some guidance on how to get it up and running. The suite was based on Hasura’s <a href="https://github.com/hasura/graphql-bench/tree/ada0120ed2b7b25d780c6fed65b0269a95cc7a90">graphql-bench suite</a>, but quite heavily modified and with the benchmarking tool wrk2 replaced by vegeta. It took quite a lot of time and effort to get it running reliably unattended, but with Prisma’s permission I’ve published my heavily modified version of it <a href="https://github.com/benjie/graphql-bench-prisma">on GitHub</a>.</p><p>To make the results reproducible I decided to run it on a Digital Ocean 8GB RAM compute-optimised droplet. I’ve provided detailed instructions in the <a href="https://github.com/benjie/graphql-bench-prisma/blob/master/README.md">README</a> on how to set up a similar environment for yourself so that you can validate my findings.</p><blockquote>I’ve provided detailed instructions in the <a href="https://github.com/benjie/graphql-bench-prisma/blob/master/README.md">README</a> on how to set up a similar environment</blockquote><p>The test suite as configured takes about 15 hours to run on the Digital Ocean Droplet. You can easily shorten that by simply editing bench.json to not record so many data points — but beware that according to @do4gr, the Prisma engineer responsible for the benchmarks, because Prisma is written in Scala and runs on the JVM it needs more time to get the JIT up to speed than PostGraphile (which is Node.js-based). @do4gr stated that “Prisma was only fully warmed up after more than 100k requests” and suggested that warming up slowly is important to an accurate benchmark on Prisma’s performance.</p><p>To accommodate Prisma’s preferences I give each environment a full 5 minute warmup period, then let it rest for 15 seconds before jumping into the testing. Each test performs requests at a constant rate lasting 60 seconds and then the service gets a 15 second respite before moving onto the next test. We use different rps (requests per second) values for the different GraphQL queries because some are significantly heavier than others, and thus need a smaller range and higher resolution (not even PostGraphile can resolve prisma_deeplyNested at 3000rps!).</p><blockquote><em>When I set up the suite I followed the instructions @do4gr provided for benchmarking Prisma (using the Docker image prismagraphql/prisma:1.8-beta), and also benchmarked the current npm version of PostGraphile (v4.0.0-beta.9), and the next version of PostGraphile which will include the optimisations and features listed above (available via npm as </em><em>postgraphile@next, or v4.0.0-beta.9.3).</em></blockquote><h4>Show me the results!</h4><p>Okay, enough chit-chat — time to show some numbers!</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2FeDbR4c3pJJZoQ%2Ftwitter%2Fiframe&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FeDbR4c3pJJZoQ%2Fgiphy.gif&amp;image=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FeDbR4c3pJJZoQ%2F200.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="326" frameborder="0" scrolling="no"><a href="https://medium.com/media/ee6fa6a92ac4631da2d64a09fcc50d0e/href">https://medium.com/media/ee6fa6a92ac4631da2d64a09fcc50d0e/href</a></iframe><p>Importantly I <em>was</em> able to reproduce the effect from Prisma’s website — this was on a simple query that requests just 2 fields from the first 20 rows in a database table. On the test environment outlined above, Prisma reaches an impressive 2000rps for this simple query! The current version of PostGraphile starts struggling after 1700rps. However, thanks to the improvements listed above, the next version of PostGraphile takes a strong lead hitting 3000rps with sub-50ms latency — more than 50% more requests per second than Prisma — and even gets past 3250rps before it starts dropping connections.</p><blockquote>the next version of PostGraphile takes a strong lead hitting 3000rps with sub-50ms latency — more than 50% more requests per second than Prisma</blockquote><pre># PostGraphile@next<br>query tracks_media_first_20 {<br>  allTracksList(first: 20) {<br>    trackId<br>    name<br>  }<br>}<br># Prisma<br>query tracks_media_first_20 {<br>  tracks(first:20)<br>  {<br>    id<br>    Name<br>  }<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EKuC71Ems6kNyWoAYTeLaA.png" /><figcaption>(Lower and to the right is better.) Prisma beats the current version of PostGraphile in the sub-50ms latency game by 2000rps to 1600; but the next version of PostGraphile takes an incredible lead with sub-50ms latency at an astounding 3000rps — that’s 50% more requests per second than Prisma achieves. (I’m not sure what caused the spike in latency for prisma at 1450rps; you should ignore it.)</figcaption></figure><p>Despite PostGraphile’s strong lead, it’s important to keep in mind that this synthetic benchmark is not the kind of query that most users would be issuing to a PostGraphile server — they’re likely to want to traverse the graph at least a little bit!</p><blockquote><em>Once you get into queries that actually do use graph traversal, even the current version of PostGraphile takes a clear lead immediately. But we’ve widened the gap with </em><em>postgraphile@next anyway 😁</em></blockquote><p>This next query requests all the albums from a particular artist, the tracks within that album and the genre name of each track. (Note: this query was from Hasura’s and hence Prisma’s test suite, I didn’t invent any of the queries in this post.) <strong>PostGraphile can serve over 4x as many of these queries per second as Prisma while staying below the 50ms line in the 95th percentile latency chart!</strong></p><pre># PostGraphile@next<br>query albums_tracks_genre_some {<br>  allAlbumsList(condition: {artistId: 127}) {<br>    artistId<br>    title<br>    tracksByAlbumIdList {<br>      trackId<br>      name<br>      genreByGenreId {<br>        name<br>      }<br>    }<br>  }<br>}<br># Prisma<br>query albums_tracks_genre_some {<br>  albums(where: {Artist: {ArtistId: 127}}) {<br>    AlbumId<br>    Title<br>    Tracks {<br>      TrackId<br>      Name<br>      Genre {<br>        Name<br>      }<br>    }<br>  }<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rsRR202FXcTzxBa0GSiBGQ.png" /><figcaption>(Lower and to the right is better.) Prisma starts flagging after 300rps; postgraphile after 900rps; but postgraphile@next not until after 1450rps!</figcaption></figure><p>Next, we look at a more complex query prisma_deeplyNested that Prisma added to their test suite (note the formatting is verbatim from the test suite):</p><pre># Postgraphile@next<br>query prisma_deeplyNested {<br>  allAlbumsList(condition: {artistId: 127}) {<br>    albumId<br>    title<br>    tracksByAlbumIdList {<br>      trackId<br>      name<br>      genreByGenreId {<br>        name<br>      }<br>    }<br>    artistByArtistId {<br>      albumsByArtistIdList {<br>        tracksByAlbumIdList {<br>          mediaTypeByMediaTypeId {<br>            name<br>          }<br>          genreByGenreId {<br>            name<br>          }<br>        }<br>      }<br>    }<br>  }<br>}<br># Prisma<br>query prisma_deeplyNested {albums(where: {Artist: {ArtistId: 127}}) { AlbumId Title  Tracks {TrackId Name Genre { Name } }  Artist{ Albums{ Tracks{ MediaType{   Name } Genre{ Name } } }  }}}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KGgngIijPXiaKn43W2E2sQ.png" /><figcaption>(Lower and to the right is better.) Prisma hits &gt;50ms before 100rps, postgraphile survives beyond 400rps and postgraphile@next makes it past an impressive 550rps before crossing the 50ms barrier.</figcaption></figure><p>Another important way to look at the data is to look at the number of successful responses completed, rather than the latency.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eTnkLUx-eZ6wXvz0xGwR_Q.png" /><figcaption>(Higher is better.) Successful requests completed when serving X requests per second over a period of 60 seconds. For the GraphQL query `albums_tracks_genre_some` Prisma serves 300rps without dropping any connections; current PostGraphile reaches 1000rps; but PostGraphile@next hits 1450rps before dropping any connections!</figcaption></figure><h4>Browse the data for yourself</h4><blockquote><em>The graphs above are screenshots of an open source webpage I built to browse the results, hosted by now.sh. Check it out, </em><a href="http://graphql-bench-visualizer.now.sh/"><em>here</em></a><em>.</em></blockquote><p>The webpage allows you to browse all 4 queries that I profiled¹, and choose from the stats: average/max latency, 50th/95th/99th percentile latency, successful request count and failed request count.</p><p>I apologise for the lack of pretty styles; I don’t have the design resources that Prisma have! (The source can be found within the benchmark repository on GitHub <a href="https://github.com/benjie/graphql-bench-prisma/tree/master/visualizer">here</a>.)</p><p>¹ <em>Technically I also profiled </em><em>albums_tracks_genre_all but the results came back with Prisma reporting no successes at even 1 rps, so I discounted it from the results since I don’t have time to look into it.</em></p><h4>Conclusion</h4><blockquote><em>As you can see from the graphs, the next version of PostGraphile outperforms Prisma for even simple queries, and the more complex a query becomes the wider PostGraphile’s lead. PostGraphile is designed to serve both simple and complex queries extremely rapidly without requiring complex setup.</em></blockquote><p>These performance results don’t mean that we’re resting on our laurels — there’s still a huge number of things we can do to improve PostGraphile performance further— if you want to support this then please<em> give generously to </em><a href="https://www.patreon.com/benjie"><em>my Patreon</em></a>! The results in this post came from just 8 hours work on the low hanging fruit; think what I could do with a month!</p><h4>Couldn’t have done it without my Patreon supporters ❤️</h4><p>I’d like to take this opportunity to send more <strong>heart-felt thanks to </strong><a href="https://www.patreon.com/benjie"><strong>my Patreon supporters</strong></a>. Knowing that these <a href="https://github.com/graphile/postgraphile/blob/master/SPONSORS.md">14 wonderful folks</a> value my work enough to put their hand in their pocket and support it makes a huge difference to my motivation — they really keep me going. It’s easy to become weighed down in Open Source — especially because <em>most of the time you have no idea who is even using your software until they have an issue</em> — but this concrete support means the world to me! Thank you all 🙏</p><p>If you or your company would like to support my work on PostGraphile or hear what it can do for you, please get in touch on via <a href="https://twitter.com/Benjie">@Benjie on Twitter</a> or just head straight to <a href="https://www.patreon.com/benjie">my Patreon</a> 😉</p><blockquote><em>I’m also starting to build some </em><a href="https://www.graphile.org/postgraphile/pricing/"><em>commercial features</em></a><em> around PostGraphile, so if this interests you please </em><a href="https://twitter.com/Benjie"><em>get in touch</em></a><em> — I’m interested to hear what your company would like to see in a professional or enterprise PostGraphile offering!</em></blockquote><h4>Say “hi” at GraphQL Europe in June!</h4><p>Coming up in just under a month, on June 15th, is the <a href="https://www.graphql-europe.org/">GraphQL Europe conference</a> in Berlin (tickets are still available). I’ll be there among the crowd, do come and say “hi!” I’ll be hanging around for a few days afterwards, so if you happen to be in the area, get in touch via <a href="https://twitter.com/Benjie">my Twitter</a>.</p><h4>Benchmark limitations / further plans</h4><blockquote>There’s a lot of issues with this benchmark process.</blockquote><p>I’d like to think that I’ve improved a number of issues over Hasura’s and Prisma’s benchmarks, but there are still some serious shortcomings. Prisma are keen to set up a benchmarking framework that different providers in the GraphQL ecosystem can use to benchmark <em>their own</em> software, I would definitely like to see this go ahead.</p><blockquote><em>There’s quite a lot that needs doing to make these tests more fair. Here are some of the inadequacies of the benchmarking I performed in this post:</em></blockquote><ol><li><strong>The databases differed.</strong> I ran Prisma against their stable MySQL implementation (as advised by them) rather than against PostgreSQL, so we were effectively benchmarking the databases along with the GraphQL software.</li><li><strong>The GraphQL queries differed.</strong> They don’t need to — both PostGraphile and Prisma support renaming GraphQL fields—it would be good to be sending exactly the same JSON blob to both servers so that differences in performance cannot be blamed on the difference in field names or whitespace.</li><li><strong>Loading the sample dataset into the databases differed.</strong> Though the tests should use the same dataset, because one was loaded via SQL file into PostgreSQL whereas the other was loaded with a proprietary tool into the Prisma cluster it’s hard to verify that the datasets are equivalent, including checking that they have the same indexes, etc. It would be best if we could have a single database that all the benchmarks run against.</li><li><strong>Everything ran on the same machine.</strong> The benchmarking tool, GraphQL software, and databases should all run on <em>independent</em> hardware such that they do not compete for resources and interfere with each other.</li><li><strong>Everything ran on a virtual machine.</strong> The benchmarks should run on dedicated physical hardware so that they’re unaffected by fluctuations in resource usage from other tenants on the same box. (This is why I chose the compute-optimise droplets, but dedicated hardware would be better still.)</li><li><strong>The recorded metrics should be widened</strong> — for example it would be great to monitor CPU usage, memory usage, or even energy usage of the different solutions when resolving the same queries.</li><li><strong>Consistent configurations should be used for each solution</strong> — how many connections can it make to the database? Must it use transactions? How many cores can it use? Should it produce logs? Is it okay to configure the environments differently because their databases have different characteristics?</li><li><strong>Testing should be performed against a larger data set. </strong>This test was ran against the chinook data set that Hasura used, however it might be better to run tests against much larger (e.g. many-gigabyte) databases, this will give a much better impression of how each software treats the database when the entire data set can’t fit in RAM.</li><li>I’m not aware of any <strong>performance throttling</strong>, but if you run a benchmark long enough and hard enough the hypervisor may throttle it, or the hardware may do so automatically if there are any thermal issues. There’s no detection of this in the current suite.</li><li><strong>GraphQL-specific response validation.</strong> I noticed quite early on that Prisma will sometimes fail with a GraphQL error but still produce a 200 status code. This is acceptable GraphQL behaviour (“GraphQL successfully resolved to this error”), but the benchmarking tool vegeta is only set up in the suite to monitor for status codes. It’s possible (if not likely!) that things are going wrong under the hood without us knowing. Any response validation that did take place, however, would have to be very careful to avoid contaminating the benchmark results with different processing times…</li><li><strong>Error logging</strong>: when Prisma was overwhelmed it was writing stack traces to Docker’s logs. This may have had a noticeable negative impact on performance, causing a cascading failure. But on top of this, it also <em>filled up the hard drive on the server with Docker logs</em>, which broke the first benchmark after about 5 hours. All docker-compose.yml files are now set up with a log limit to prevent this flooding, but we should agree on what the systems being benchmarked should do in the case of errors to make comparisons fair.</li><li><strong>Garbage collection. </strong>Both Prisma and PostGraphile use garbage-collected languages; I believe this contributes to the “bumps” in the charts — e.g. where the system appears to suddenly go slower and then speed up again. Seeing how the system deals with GC is an important metric, but when you’re only benchmarking 60 second windows you’re sometimes going to hit a GC run, and sometimes not. One way to solve this is to force GC before each test. Another might be to extend the test period so that the GC results get absorbed in.</li><li><strong>Unnatural load. </strong>Most public-facing servers on the internet deal with varying load from second to second; these synthetic benchmarks do not model that well at all — once the system stumbles there’s no chance of it getting back up again because the load never lets up, even for a few milliseconds, which can allow GC pauses and JIT changes to allow a queue to build up that it cannot then clear.</li><li><strong>The tests only ran once.</strong> If a system process kicked in at one point, that may have interfered with one of the tests. It would be good to run the tests multiple times and average the results (perhaps even excluding outliers); however with the suite already taking 15 hours to execute that was unachievable for me.</li><li><strong>I’m not a Prisma engineer.</strong> Benchmarking third party code is challenging — only they know how best to set up that software, and <em>the incentives are not aligned</em> for you to go out of your way to research how to set the tests up right for them, or even how to write sensible queries. I sought a lot of guidance from Prisma on running these tests (and use the queries that they provided), but still there could be issues with what I have done or mistakes that I have made during setup.</li><li><strong>Doesn’t include Hasura in the tests. </strong>This is simply because I used Prisma’s test suite, and I’ve absolutely no familiarity with Hasura and didn’t have time to re-introduce benchmarking on it in a way that would be meaningful.</li></ol><p>Thanks for reading! Check out <a href="https://www.graphile.org/postgraphile/">PostGraphile</a>, follow me on Twitter: <a href="https://twitter.com/benjie">@Benjie</a> or GitHub: <a href="https://github.com/benjie">@Benjie</a>, and consider giving to to <a href="https://www.patreon.com/benjie">my Patreon</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e66b4c511160" width="1" height="1" alt=""><hr><p><a href="https://medium.com/graphile/how-i-made-postgraphile-faster-than-prisma-graphql-server-in-8-hours-e66b4c511160">How I Made PostGraphile Faster Than Prisma GraphQL Server In 8 Hours</a> was originally published in <a href="https://medium.com/graphile">Graphile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[PostGraphile v4 Released]]></title>
            <link>https://medium.com/graphile/postgraphile-v4-released-9dcb117d3e69?source=rss----907daaddfec9---4</link>
            <guid isPermaLink="false">https://medium.com/p/9dcb117d3e69</guid>
            <category><![CDATA[graphql]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[postgraphile]]></category>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[postgres]]></category>
            <dc:creator><![CDATA[Benjie Gillam]]></dc:creator>
            <pubDate>Mon, 28 Jan 2019 19:03:34 GMT</pubDate>
            <atom:updated>2018-10-02T14:01:13.131Z</atom:updated>
            <content:encoded><![CDATA[<p>After many months of development, testing and iteration it is my great pleasure to announce that PostGraphile v4 is officially available! Everyone using PostGraphQL v3 should upgrade to PostGraphile at their earliest convenience — if you need help with the migration then pop into <a href="http://discord.gg/graphile">our Discord chat</a>.</p><p>Despite 80% of the codebase having been replaced with the new Graphile GraphQL Engine, v4 manages to achieve very high compatibility with v3, so most users should find the upgrade fairly painless.</p><p>The main focusses of v4 have been performance, customisability and stability.</p><h4>Performance</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*b7TLSVe-xlkmmLjMTBvCSg.png" /></figure><p>PostGraphile performance has been greatly improved thanks to the new Graphile Engine which enables us to compile an entire GraphQL query tree into just one SQL statement. This then passes the task of efficiently executing your query over to the heavily optimised query planner in PostgreSQL, which uses advanced techniques such as relational algebra and genetic algorithms to find the fastest plan quickly. We’ve also performed a large number of optimisations in JavaScript-land, which has lead to code that is more easily optimised by the JIT, and reduced work for the garbage collector — resulting in a 90%+ reduction in peak memory usage. We see typical performance improvements for webpage queries at around 17×, but the more complex the query is, the better PostGraphile v4’s performance — for a 4-level deep query we hit 55× the performance of v3!</p><h4>Customisability</h4><p>Reading over the GitHub issues when I became maintainer of the (then) PostGraphQL project over a year ago, I realised that quite a few people desired the ability to customise their GraphQL schema. There were even a small number of people maintaining public forks of PostGraphQL so that they could add that one feature that was important to them; but these forks would quickly become out of date as the effort required to keep them in sync was too great. PostGraphQL also exposed too much by default, making schemas seem huge and unwieldy at times. It was clear to me that PostGraphile needed to solve these issues — doing more for the user out of the box, giving them more control over the generated GraphQL schema, and allowing users to enhance their schemas as they saw fit; so I set out to address these issues in version 4.</p><p>Out of the box, PostGraphile now ignores resources that come from PostgreSQL extensions, so you can now use the default public schema in PostgreSQL without your GraphQL being flooded with helper functions from extensions such as citext and pgcrypto(you can opt out of this should you so desire).</p><p>Version 4 also introduces the --no-ignore-rbac toggle which inspects the database permissions and omits things that the user has not been granted access to. This means that if you don’t grant SELECT on a table to your PostGraphile role, it will not appear in the generated schema. If you only grant UPDATE on two columns in your table, then only those two columns will be available in the update mutation. We highly recommend that all users enable this flag, it will probably be enabled by default in v5.</p><p>Another feature v4 introduces is <a href="https://www.graphile.org/postgraphile/smart-comments/">smart comments</a>. Smart comments enable you to add tags to tables, columns, functions, constraints, etc. so that the system can handle them slightly differently. For example, you can use the @omit all tag to prevent the generation of the allFoos root query field, or the @deprecated tag to mark a field as deprecated. You can use @name and variants to give a different name to a field or type in the generated GraphQL schema. And this functionality is not limited to these specific tags — plugins can also be influenced by smart comments.</p><p>And speaking of plugins — v4 introduces a powerful plugin system powered by Graphile Engine. This GraphQL engine was built from the ground up to enable incredible performance and extensibility. And we’re not kidding — in fact the entire schema generation in PostGraphile is powered by <a href="https://github.com/graphile/graphile-engine/tree/master/packages/graphile-build/src/plugins">over 35</a> <a href="https://github.com/graphile/graphile-engine/tree/master/packages/graphile-build-pg/src/plugins">plugins</a>, and you can add, remove or replace plugins to get the schema that you desire without having to maintain a fork of the entire project. A <a href="https://www.graphile.org/postgraphile/community-plugins/">community of plugin builders</a> has formed during the testing period of PostGraphile v4 and has built some really amazing plugins — one to check out in particular is <a href="https://github.com/graphile-contrib/postgraphile-plugin-connection-filter">Matt’s connection filter plugin</a> which adds powerful filtering capabilities to PostGraphile connections.</p><p>The naming system (“inflector”) in PostGraphile is also pluggable, so if you don’t like how we manipulate the names of your database fields, or if you don’t like our allRows naming, you can change it easily. You can check out my <a href="https://github.com/graphile-contrib/pg-simplify-inflector">inflector simplifier plugin</a> to see this in action (I definitely recommend using this once you’re familiar with PostGraphile), or make your own with our <a href="https://www.graphile.org/postgraphile/make-add-inflectors-plugin/">handy </a><a href="https://www.graphile.org/postgraphile/make-add-inflectors-plugin/">makeAddInflectorsPlugin helper</a>.</p><h4>Stability</h4><p>Version 4 fixes a large number of bugs and edge cases that were present in v3. It also focusses on reducing memory usage, helping your servers run faster for longer. One of the reasons for the long development and testing phase has been that we wanted to make sure that v4 was a solid foundation on which to build, ensuring that we do not cause any breaking changes in the future. Thanks largely to the community testing it and filing issues, writing powerful plugins, and pushing the boundaries of the software, I’m very confident in today’s release.</p><p>We’ve also made it a lot easier for users to figure out what’s going wrong — the errors that PostGraphile outputs now are no longer cryptic errors as they have been in the alpha and beta periods, but instead helpful errors detailing not only what went wrong, but in many cases hinting at how you might fix it. If you come across any cryptic error messages, please do <a href="https://github.com/graphile/postgraphile/issues/new">file an issue</a> so that we can fix it.</p><h4>Getting Started</h4><p>We’ve dedicated a lot of time to the PostGraphile documentation, and this will be continually improved over the coming weeks and months. We’ve included a full <a href="https://www.graphile.org/postgraphile/v4-new-features/">Version 4 Feature Guide</a> and <a href="https://www.graphile.org/postgraphile/v3-migration/">Version 3 to Version 4 Migration Guide</a> — so do check them out whilst you upgrade.</p><p>Getting started with PostGraphile is as easy as giving it your PostgreSQL database connection string, e.g. for a local database called my_db, assuming you already have Node.js 8.6 or higher installed you can use the bundled npx utility and run:</p><p>npx postgraphile -c my_db --watch</p><p>The watch mode will monitor your PostgreSQL database for changes (added or removed tables, columns, constraints, comments, functions, etc) and automatically update the GraphQL schema. Our built in GraphiQL UI will also automatically update the documentation browser, without losing your state.</p><h4>Please Support PostGraphile Development</h4><p>PostGraphile version 4 has been a labour of love, but sadly love doesn’t pay the bills! Sponsorship is now close to funding a day per week dedicated to PostGraphile development, and this support is growing every month which is already leading to more features and faster releases. Please consider if you can support PostGraphile development <a href="https://www.patreon.com/benjie">via Patreon</a> — a regular donation means more time spent on PostGraphile.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/502/1*6HUenBpOQRSCXdCCY6VSFA.png" /></figure><p>Whether you can sponsor PostGraphile or not, there are other ways you can help:</p><ul><li>⭐ <a href="https://github.com/graphile/postgraphile">Star the repository</a> on GitHub</li><li>Talk about PostGraphile <a href="https://twitter.com/intent/tweet?text=PostGraphile%20v4%20is%20released%20-%20instant,%20high-performance,%20secure%20GraphQL%20API%20for%20your%20PostgreSQL%20database!%20%F0%9F%8E%89%20https://medium.com/@Benjie/postgraphile-v4-released-9dcb117d3e69">on social media</a></li><li><a href="https://chads.website/development/2018/08/03/How-GraphQL-Saved-My-Project.html">Write</a> <a href="https://medium.com/@awesboss/how-to-find-missing-indexes-on-foreign-keys-2faffd7e6958">blog</a> <a href="https://itnext.io/automatically-building-and-maintaining-graphql-apis-with-postgresql-and-postgraphile-c497636abd29">posts</a> about using PostGraphile</li><li>Demonstrate your projects at local meet ups</li></ul><p>And follow our new <a href="https://twitter.com/graphilehq">Twitter account @GraphileHQ</a> for more updates.</p><p>The more people that use and support PostGraphile, the faster fixes and features can be added, and everyone benefits!</p><p>I want to take this opportunity to say a huge <strong><em>THANK YOU</em></strong> to the community for supporting my work on PostGraphile, without you version 4 would not be nearly as exciting a release!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9dcb117d3e69" width="1" height="1" alt=""><hr><p><a href="https://medium.com/graphile/postgraphile-v4-released-9dcb117d3e69">PostGraphile v4 Released</a> was originally published in <a href="https://medium.com/graphile">Graphile</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>