← Extractions

Optimizing Rails apps with a GraphQL layer (Caio Almeida, wroclove.rb 2024)

Caio Almeida from Meedan shares eight years of hard-won lessons running a Rails + GraphQL monolith (the Check fact-checking platform). He walks through performance testing, monitoring at HTTP/query/field levels, N+1 solutions (graphql-batch, graphql-preload, look-ahead), safeguards (max depth, timeout), caching (graphql-ruby-fragment-cache, event-based cached fields), query batching via multiplex, and Q&A on authorization and whether to go back to REST.

Model
claude-opus-4-7
Ingestion
3f33be13
Input tokens
110,123
fresh
41,671
cached
55,428
cache write
13,024
Output tokens
11,701
Duration
167.5s
Roundtrips
4
Tool calls
10
Cost
$0.00
Nodes/edges extracted
34 / 54
Read set (nodes/edges)
68 / 2

Nodes (34)

create Sentry tool
kind (empty) tool
name (empty) Sentry
slug (empty) sentry
attrs (empty) {"category" => "service"}
description (empty) Error-tracking service Meedan integrates with their Rails app. A graphql-ruby timeout handler calls Sentry.notify whe...
short_description (empty) Error tracking and alerting service.
create PagerDuty tool
kind (empty) tool
name (empty) PagerDuty
slug (empty) pagerduty
attrs (empty) {"category" => "service"}
description (empty) On-call alerting service triggered by uptime incidents (e.g. when an HTTP request exceeds a latency threshold) so tha...
short_description (empty) On-call incident alerting service.
create Relay tool
kind (empty) tool
name (empty) Relay
slug (empty) relay
attrs (empty) {"category" => "library"}
description (empty) Facebook's GraphQL client for React. Meedan's Check front-end uses React + Relay; the Relay network layer can be twea...
short_description (empty) React GraphQL client with declarative data-fetching.
update Caio Almeida person
attrs (empty) {"country" => "Brazil", "rails_since" => "2018"}
description Conference speaker. Brazilian software engineer based in Brazil, working with Rails since 2018. Joined Meedan in 2016 as a software engin...
short_description Conference speaker. Brazilian software engineer at Meedan, Rails/GraphQL practitioner.
create Meedan company
kind (empty) company
name (empty) Meedan
slug (empty) meedan
attrs (empty) {"industry" => "nonprofit / fact-checking tools", "headquarters" => "San Francisco"}
description (empty) Nonprofit based in San Francisco that develops tools for collaborative fact-checking. Its main product, Check, was fu...
short_description (empty) San Francisco-based nonprofit building collaborative fact-checking tools.
create Check project
kind (empty) project
name (empty) Check
slug (empty) check
attrs (empty) {"status" => "active", "license" => "open-source", "architecture" => "microservices, headless Rails GraphQL API"}
description (empty) Meedan's main product: an open-source platform for fact-checking organizations around the world to track and verify m...
short_description (empty) Meedan's open-source collaborative fact-checking platform.
create AWS CloudWatch tool
kind (empty) tool
name (empty) AWS CloudWatch
slug (empty) aws-cloudwatch
attrs (empty) {"category" => "service"}
description (empty) AWS logging service where Meedan collects Rails HTTP request logs. Useful for total request duration but not for pinp...
short_description (empty) AWS logging and metrics service.
update Optimizing performance in Rails apps with GraphQL layer talk
description Talk at wroclove.rb 2024. Conference talk at wroclove.rb 2024 by Caio Almeida of Meedan, sharing eight years of lessons building and operating ...
short_description Talk at wroclove.rb 2024. Caio Almeida's wroclove.rb 2024 talk on performance patterns for Rails + GraphQL.
update wroclove.rb 2024 event
No changes recorded.
update GraphQL tool
description API query language cited as having use cases where JSON API 'basically sucks'. Panel advice: be open-minded and pick ... Query language describing data using a type system, with bindings for many programming languages. Open-sourced by Fac...
create graphql-ruby tool
kind (empty) tool
name (empty) graphql-ruby
slug (empty) graphql-ruby
attrs (empty) {"category" => "library", "language" => "Ruby"}
description (empty) The canonical Ruby implementation of GraphQL. Early versions used DSL-style definers that were hard to write and reus...
short_description (empty) Ruby gem implementing the GraphQL specification for Ruby/Rails apps.
create graphql-batch tool
kind (empty) tool
name (empty) graphql-batch
slug (empty) graphql-batch
attrs (empty) {"category" => "library", "language" => "Ruby"}
description (empty) Ruby gem originally implemented by Shopify that batches data loading in graphql-ruby resolvers. Using a RecordLoader ...
short_description (empty) Shopify gem for batch-loading associations in GraphQL resolvers.
create graphql-preload tool
kind (empty) tool
name (empty) graphql-preload
slug (empty) graphql-preload
attrs (empty) {"category" => "library", "language" => "Ruby"}
description (empty) Ruby gem used to preload has_many associations (e.g. a post's tags) at the beginning of a GraphQL query scope, avoidi...
short_description (empty) Ruby gem that eager-loads has_many associations in GraphQL resolvers.
create graphql-ruby-fragment-cache tool
kind (empty) tool
name (empty) graphql-ruby-fragment-cache
slug (empty) graphql-ruby-fragment-cache
attrs (empty) {"category" => "library", "language" => "Ruby"}
description (empty) Ruby gem that caches fragments (individual fields) at the GraphQL API layer in graphql-ruby. Fields declare cache_fra...
short_description (empty) Gem for caching individual fields at the GraphQL API layer.
create Honeycomb tool
kind (empty) tool
name (empty) Honeycomb
slug (empty) honeycomb
attrs (empty) {"category" => "service"}
description (empty) Observability tool used at Meedan to trace GraphQL requests via OpenTelemetry. Gives per-request spans for parsing, v...
short_description (empty) Observability SaaS built around OpenTelemetry tracing.
create OpenTelemetry tool
kind (empty) tool
name (empty) OpenTelemetry
slug (empty) opentelemetry
attrs (empty) {"category" => "platform"}
description (empty) Open observability standard that instruments applications with spans and metrics. Used under the hood by Honeycomb to...
short_description (empty) Vendor-neutral standard for distributed tracing and metrics.
create Apollo GraphQL tool
kind (empty) tool
name (empty) Apollo GraphQL
slug (empty) apollo-graphql
attrs (empty) {"category" => "service"}
description (empty) GraphQL platform used by Meedan for schema visualization (acting as living documentation and schema-change tracking) ...
short_description (empty) GraphQL platform offering schema visualization, monitoring and client tooling.
update Pundit tool
description Popular Ruby authorization gem; used in Adrian's talk as the example runtime dependency declared in an engine's gemsp... Popular Ruby authorization gem. Meedan adopted Pundit when they first built Check with GraphQL, because graphql-ruby ...
short_description Minimal authorization Ruby gem using policy classes. Ruby gem for object-level authorization policies.
update N+1 Queries concept
description Common ORM query-per-row performance problem. Sergyenko lists it as a core thing Ruby engineers working with data mus... Common ORM performance problem where the number of database queries is proportional to the number of rows loaded. In ...
create Nested GraphQL query bottleneck concept
kind (empty) concept
name (empty) Nested GraphQL query bottleneck
slug (empty) nested-graphql-query-bottleneck
attrs (empty) {"category" => "pattern"}
description (empty) Concept discussed in the talk: because GraphQL is highly expressive, clients can issue deeply nested queries (and eve...
short_description (empty) Deeply nested GraphQL queries hiding expensive or circular data fetches.
create GraphQL look_ahead concept
kind (empty) concept
name (empty) GraphQL look_ahead
slug (empty) graphql-look_ahead
attrs (empty) {"category" => "pattern"}
description (empty) graphql-ruby feature where a field receives a look_ahead object describing the tree of fields the caller requested. R...
short_description (empty) graphql-ruby feature exposing the requested query tree to resolvers.
create GraphQL max_depth concept
kind (empty) concept
name (empty) GraphQL max_depth
slug (empty) graphql-max_depth
attrs (empty) {"category" => "practice"}
description (empty) A graphql-ruby schema option that rejects queries nested beyond a configured depth (e.g. 4). Simple safeguard against...
short_description (empty) Schema-level limit on nesting depth of incoming GraphQL queries.
create GraphQL query timeout concept
kind (empty) concept
name (empty) GraphQL query timeout
slug (empty) graphql-query-timeout
attrs (empty) {"category" => "practice"}
description (empty) Control added to a graphql-ruby schema that caps the total execution time of a GraphQL query. When exceeded, the hand...
short_description (empty) Per-query maximum execution time enforced at the GraphQL schema level.
create GraphQL query batching concept
kind (empty) concept
name (empty) GraphQL query batching
slug (empty) graphql-query-batching
attrs (empty) {"category" => "pattern"}
description (empty) Pattern where a GraphQL client (Apollo's client-side batching, or React Relay's network layer) combines queries trigg...
short_description (empty) Combining multiple GraphQL queries into one HTTP request and executing them concurrently.
create Event-based GraphQL field caching concept
kind (empty) concept
name (empty) Event-based GraphQL field caching
slug (empty) event-based-graphql-field-caching
attrs (empty) {"category" => "pattern"}
description (empty) Caching approach Meedan built in-house: each expensive cached field declares a starting value and a list of model eve...
short_description (empty) Explicit list of model events that invalidate a cached GraphQL field.
create GraphQL performance regression tests concept
kind (empty) concept
name (empty) GraphQL performance regression tests
slug (empty) graphql-performance-regression-tests
attrs (empty) {"category" => "practice"}
description (empty) Practice of writing tests (e.g. Minitest assert_queries helper) that assert how many database queries a given GraphQL...
short_description (empty) Minitest helpers asserting maximum database queries per GraphQL operation.
create Premature optimization concept
kind (empty) concept
name (empty) Premature optimization
slug (empty) premature-optimization
attrs (empty) {"category" => "practice"}
description (empty) Well-known computer-science adage cited as the 'root of all evil'. In the talk used to temper optimization advice: an...
short_description (empty) Classic warning that optimizing too early wastes effort on the wrong code.
create Monitoring is the most important optimization habit takeaway
kind (empty) takeaway
name (empty) Monitoring is the most important optimization habit
slug (empty) monitoring-is-the-most-important-optimization-habit
attrs (empty) {"type" => "recommendation"}
description (empty) Speaker's single most-emphasized takeaway: you can't improve what you don't measure. Set up monitoring at multiple le...
short_description (empty) Without layered monitoring you can't identify real GraphQL bottlenecks.
create Make performance a team mindset takeaway
kind (empty) takeaway
name (empty) Make performance a team mindset
slug (empty) make-performance-a-team-mindset
attrs (empty) {"type" => "recommendation"}
description (empty) Performance is an ongoing process, not a one-off sprint. For sustained adoption of monitoring and optimization tools,...
short_description (empty) Optimization must be continuous and owned by the whole engineering team.
create Always evaluate trade-offs of GraphQL optimizations takeaway
kind (empty) takeaway
name (empty) Always evaluate trade-offs of GraphQL optimizations
slug (empty) always-evaluate-trade-offs-of-graphql-optimizations
attrs (empty) {"type" => "insight"}
description (empty) Every GraphQL optimization (extra gems, look_ahead resolvers, custom caching DSLs) adds dependencies, learning curve ...
short_description (empty) Performance wins like look_ahead can cost readability and onboarding time.
create Delay mutations to background jobs takeaway
kind (empty) takeaway
name (empty) Delay mutations to background jobs
slug (empty) delay-mutations-to-background-jobs
attrs (empty) {"type" => "recommendation"}
description (empty) For GraphQL mutations with heavy side-effects — calls to external services, bulk operations like 'select all + tag' o...
short_description (empty) Offload slow mutation work (external calls, bulk ops) to background jobs.
create Denormalization vs graphql-batch / graphql-preload question
kind (empty) question
name (empty) Denormalization vs graphql-batch / graphql-preload
slug (empty) denormalization-vs-graphql-batch-graphql-preload
attrs (empty) {"answer_summary" => "Didn't evaluate denormalization specifically; graphql-batch was the first fix, and because Chec...
description (empty) Audience question asking whether the team evaluated data denormalization (e.g. adding a tags field directly on the Po...
short_description (empty) Did you compare denormalizing fields versus using batch/preload gems?
create Authorization strategies in GraphQL question
kind (empty) question
name (empty) Authorization strategies in GraphQL
slug (empty) authorization-strategies-in-graphql
attrs (empty) {"answer_summary" => "Authenticate at the controller; authorize at type/field level using graphql-ruby + Pundit. Meed...
description (empty) Audience question about authorization patterns in large GraphQL apps: field level vs layer level, how layers coordina...
short_description (empty) How to handle authorization for flexible GraphQL queries?
create Have you considered going back to REST? question
kind (empty) question
name (empty) Have you considered going back to REST?
slug (empty) have-you-considered-going-back-to-rest
attrs (empty) {"answer_summary" => "No. Check is open-source with three in-house clients and many external fact-checking agencies —...
description (empty) Audience question at the end of the talk. Speaker jokes he 'scratches himself every day' but no: Check is open-source...
short_description (empty) Would you drop GraphQL and return to REST APIs?

Edges (54)

update Caio AlmeidaauthoredOptimizing performance in Rails apps with GraphQL layer
context (empty) Delivered the talk at wroclove.rb 2024.
update Optimizing performance in Rails apps with GraphQL layerpresented_atwroclove.rb 2024
context (empty) Talk given at wroclove.rb 2024 (originally scheduled for 2020 before pandemic cancellation).
create Caio Almeidaattendedwroclove.rb 2024
context (empty) Speaker at the conference.
relation (empty) attended
source_node_id (empty) 8e94e35e-1e33-48c7-ac3e-b72e4e1c8c9e
target_node_id (empty) 748e0524-a102-41d4-97dc-575881583d91
create Caio Almeidaworks_atMeedan
attrs (empty) {"role" => "software engineer", "since" => "2016"}
context (empty) Software engineer at Meedan since 2016.
relation (empty) works_at
source_node_id (empty) 8e94e35e-1e33-48c7-ac3e-b72e4e1c8c9e
target_node_id (empty) cc6d7a67-eef0-4196-9a7e-0874b4868ece
create Caio Almeidaworks_onCheck
attrs (empty) {"role" => "lead engineer of PHP→Rails rewrite"}
context (empty) Led migration of Meedan's main product Check from PHP to Rails.
relation (empty) works_on
source_node_id (empty) 8e94e35e-1e33-48c7-ac3e-b72e4e1c8c9e
target_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
create CheckusesGraphQL
context (empty) Check's core Rails API is a headless GraphQL API.
relation (empty) uses
source_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
target_node_id (empty) c6a1041c-3116-4194-b7f0-eba7cd4a7e64
create Checkusesgraphql-ruby
context (empty) Ruby implementation of GraphQL powering Check's API.
relation (empty) uses
source_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
target_node_id (empty) be81c4e9-2645-4f1d-90cc-0d6cfe93cb6c
create Checkusesgraphql-batch
context (empty) Used to batch-load belongs_to associations and avoid N+1 queries.
relation (empty) uses
source_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
target_node_id (empty) f3af2e65-d82f-4f24-81e2-ac1f84dd0b2b
create CheckusesRelay
context (empty) Check's React front-end uses Relay with query batching in the network layer.
relation (empty) uses
source_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
target_node_id (empty) 204d8f3f-4978-4072-ac57-92411341cca4
create CheckusesHoneycomb
context (empty) Monitoring GraphQL query execution via OpenTelemetry spans.
relation (empty) uses
source_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
target_node_id (empty) 9fe05a75-6726-4be8-b578-0058603267a6
create CheckusesOpenTelemetry
context (empty) Instrumentation underlying Honeycomb tracing.
relation (empty) uses
source_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
target_node_id (empty) 39ce1c2f-63e7-4a8d-859f-40e7f1bd6d4b
create CheckusesApollo GraphQL
context (empty) Schema visualization, per-field monitoring, and Slack daily summaries of slow queries.
relation (empty) uses
source_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
target_node_id (empty) cebd5aab-3634-4afe-b0a8-ba8fb96ddffc
create CheckusesAWS CloudWatch
context (empty) Collects Rails HTTP request logs.
relation (empty) uses
source_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
target_node_id (empty) a2a3a19e-767f-42a8-8776-c2fcf62c6397
create CheckusesSentry
context (empty) Receives notifications when GraphQL queries exceed timeout.
relation (empty) uses
source_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
target_node_id (empty) 9b81df6c-7817-4cd8-91a1-bfeefb7fbce8
create CheckusesPagerDuty
context (empty) Triggers on-call incidents from uptime alerts.
relation (empty) uses
source_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
target_node_id (empty) fefd3a9e-5cec-4b86-8ba8-cb49dc16f4cd
create CheckusesPundit
context (empty) Authorization enforced below GraphQL because graphql-ruby didn't offer it at the API layer when Check adopted GraphQL.
relation (empty) uses
source_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
target_node_id (empty) 1ebb50fc-98ba-48a0-8720-cbf7138c2eed
create Meedanworks_onCheck
context (empty) Check is Meedan's flagship product.
relation (empty) works_on
source_node_id (empty) cc6d7a67-eef0-4196-9a7e-0874b4868ece
target_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
create Optimizing performance in Rails apps with GraphQL layeraboutGraphQL
context (empty) Talk focuses on Rails applications with a GraphQL layer.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) c6a1041c-3116-4194-b7f0-eba7cd4a7e64
create Optimizing performance in Rails apps with GraphQL layeraboutgraphql-ruby
context (empty) Uses graphql-ruby features (types, connections, look_ahead, max_depth, multiplex, timeouts, authorization).
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) be81c4e9-2645-4f1d-90cc-0d6cfe93cb6c
create Optimizing performance in Rails apps with GraphQL layeraboutN+1 Queries
context (empty) N+1 is framed as the classic GraphQL performance problem.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) ee033151-443a-4285-aa68-fbc2e9755d06
create Optimizing performance in Rails apps with GraphQL layeraboutgraphql-batch
context (empty) Presented as the Shopify-built solution for batching belongs_to loads.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) f3af2e65-d82f-4f24-81e2-ac1f84dd0b2b
create Optimizing performance in Rails apps with GraphQL layeraboutgraphql-preload
context (empty) Presented as the solution for preloading has_many associations.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) 953a145f-a42f-477e-b099-618314e0574b
create Optimizing performance in Rails apps with GraphQL layeraboutGraphQL look_ahead
context (empty) Explains predictive preloading via look_ahead for complex nested queries.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) 7dc62afe-5967-4d13-be8e-208ed0b34e39
create Optimizing performance in Rails apps with GraphQL layeraboutGraphQL max_depth
context (empty) Shown as a simple safeguard against deep nested queries.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) c1fc40a4-acdf-4448-9404-7723b9b4ea6b
create Optimizing performance in Rails apps with GraphQL layeraboutGraphQL query timeout
context (empty) Shown as a control over whole-query execution time integrated with Sentry.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) dae7ca29-db2f-4fcb-81eb-8a2fafdaf74d
create Optimizing performance in Rails apps with GraphQL layeraboutgraphql-ruby-fragment-cache
context (empty) Demonstrated as API-layer fragment caching for expensive fields.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) 9cedcb96-c456-4d53-958c-4d50c8cb3a73
create Optimizing performance in Rails apps with GraphQL layeraboutEvent-based GraphQL field caching
context (empty) Describes Meedan's own event-based cached-field library built on Ruby meta-programming and Rails low-level caching.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) 1c63e985-d968-4dcf-b1df-b81d8e95ae75
create Optimizing performance in Rails apps with GraphQL layeraboutGraphQL query batching
context (empty) Covers Apollo/Relay client batching and graphql-ruby's multiplex on the server side.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) af9fb052-6275-447c-9689-4c6ad41c0772
create Optimizing performance in Rails apps with GraphQL layeraboutGraphQL performance regression tests
context (empty) Shown as assert_queries-based Minitest helpers to prevent N+1 regressions.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) da77f6d8-91f0-429d-8103-27a13e6ba3de
create Optimizing performance in Rails apps with GraphQL layeraboutNested GraphQL query bottleneck
context (empty) Deep/unpredictable queries are a central problem the talk addresses.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) ff9b1251-f5b4-4b6d-9bc4-bada69c5c00a
create Optimizing performance in Rails apps with GraphQL layeraboutPremature optimization
context (empty) Discusses the adage while arguing for anticipatory design where feasible.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) 5bd44190-5f0e-4459-884c-2879f0cb671f
create Optimizing performance in Rails apps with GraphQL layeraboutHoneycomb
context (empty) Used in the monitoring-level examples.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) 9fe05a75-6726-4be8-b578-0058603267a6
create Optimizing performance in Rails apps with GraphQL layeraboutApollo GraphQL
context (empty) Showcased for schema visualization and per-field performance metrics.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) cebd5aab-3634-4afe-b0a8-ba8fb96ddffc
create Optimizing performance in Rails apps with GraphQL layeraboutOpenTelemetry
context (empty) Underlying tracing standard powering Honeycomb instrumentation.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) 39ce1c2f-63e7-4a8d-859f-40e7f1bd6d4b
create Optimizing performance in Rails apps with GraphQL layeraboutCheck
context (empty) All concrete examples come from Meedan's Check application.
relation (empty) about
source_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
target_node_id (empty) 8b4e5d9c-9987-43bb-b7bd-3c9f2fc5af4a
create Monitoring is the most important optimization habitfrom_talkOptimizing performance in Rails apps with GraphQL layer
context (empty) Speaker's headline takeaway.
relation (empty) from_talk
source_node_id (empty) c8ef0a42-aae4-4376-81a5-44935f58f680
target_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
create Make performance a team mindsetfrom_talkOptimizing performance in Rails apps with GraphQL layer
context (empty) Closing recommendation on sustained adoption.
relation (empty) from_talk
source_node_id (empty) 15d45371-3d02-4f9d-bdca-6fa04549f75d
target_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
create Always evaluate trade-offs of GraphQL optimizationsfrom_talkOptimizing performance in Rails apps with GraphQL layer
context (empty) Repeated caution throughout the talk.
relation (empty) from_talk
source_node_id (empty) 4f95efd5-0dcf-4b5c-b47e-1efaf45b60d6
target_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
create Delay mutations to background jobsfrom_talkOptimizing performance in Rails apps with GraphQL layer
context (empty) Mutation-side recommendation near the end.
relation (empty) from_talk
source_node_id (empty) 7a8976ee-8174-4d74-bec9-61ca801397a3
target_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
create Denormalization vs graphql-batch / graphql-preloadasked_atOptimizing performance in Rails apps with GraphQL layer
context (empty) Q&A about alternative optimization approaches.
relation (empty) asked_at
source_node_id (empty) 2a03cf0c-0899-406f-956b-796791e214bc
target_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
create Authorization strategies in GraphQLasked_atOptimizing performance in Rails apps with GraphQL layer
context (empty) Q&A about authorization for flexible GraphQL queries.
relation (empty) asked_at
source_node_id (empty) 7250db27-6403-484d-b712-864427195e72
target_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
create Have you considered going back to REST?asked_atOptimizing performance in Rails apps with GraphQL layer
context (empty) Q&A asking if Meedan has considered reverting from GraphQL to REST.
relation (empty) asked_at
source_node_id (empty) f69d163c-ce42-4f07-a86a-fe675c2484d4
target_node_id (empty) c6952b14-5193-4339-8f6a-9ebc6f3cd440
create Authorization strategies in GraphQLaboutPundit
context (empty) Pundit is cited as the authorization gem Meedan uses.
relation (empty) about
source_node_id (empty) 7250db27-6403-484d-b712-864427195e72
target_node_id (empty) 1ebb50fc-98ba-48a0-8720-cbf7138c2eed
create Authorization strategies in GraphQLaboutgraphql-ruby
context (empty) graphql-ruby's field-level authorization and context object are the core of the answer.
relation (empty) about
source_node_id (empty) 7250db27-6403-484d-b712-864427195e72
target_node_id (empty) be81c4e9-2645-4f1d-90cc-0d6cfe93cb6c
create Denormalization vs graphql-batch / graphql-preloadaboutgraphql-batch
context (empty) Question compares denormalization with graphql-batch.
relation (empty) about
source_node_id (empty) 2a03cf0c-0899-406f-956b-796791e214bc
target_node_id (empty) f3af2e65-d82f-4f24-81e2-ac1f84dd0b2b
create Denormalization vs graphql-batch / graphql-preloadaboutgraphql-preload
context (empty) Question compares denormalization with graphql-preload.
relation (empty) about
source_node_id (empty) 2a03cf0c-0899-406f-956b-796791e214bc
target_node_id (empty) 953a145f-a42f-477e-b099-618314e0574b
create Have you considered going back to REST?aboutGraphQL
context (empty) About whether to abandon GraphQL.
relation (empty) about
source_node_id (empty) f69d163c-ce42-4f07-a86a-fe675c2484d4
target_node_id (empty) c6a1041c-3116-4194-b7f0-eba7cd4a7e64
create Caio Almeidahas_skillgraphql-ruby
attrs (empty) {"level" => "expert"}
context (empty) Uses graphql-ruby extensively in production at Meedan.
relation (empty) has_skill
source_node_id (empty) 8e94e35e-1e33-48c7-ac3e-b72e4e1c8c9e
target_node_id (empty) be81c4e9-2645-4f1d-90cc-0d6cfe93cb6c
create Caio Almeidahas_skillGraphQL
attrs (empty) {"level" => "expert"}
context (empty) Eight years operating a Rails+GraphQL product.
relation (empty) has_skill
source_node_id (empty) 8e94e35e-1e33-48c7-ac3e-b72e4e1c8c9e
target_node_id (empty) c6a1041c-3116-4194-b7f0-eba7cd4a7e64
create Caio Almeidarecommendsgraphql-batch
context (empty) First tool Meedan introduced to fix N+1 on belongs_to.
relation (empty) recommends
source_node_id (empty) 8e94e35e-1e33-48c7-ac3e-b72e4e1c8c9e
target_node_id (empty) f3af2e65-d82f-4f24-81e2-ac1f84dd0b2b
create Caio Almeidarecommendsgraphql-preload
context (empty) Recommended for preloading has_many associations.
relation (empty) recommends
source_node_id (empty) 8e94e35e-1e33-48c7-ac3e-b72e4e1c8c9e
target_node_id (empty) 953a145f-a42f-477e-b099-618314e0574b
create Caio AlmeidarecommendsHoneycomb
context (empty) Cited as successfully used for GraphQL tracing via OpenTelemetry.
relation (empty) recommends
source_node_id (empty) 8e94e35e-1e33-48c7-ac3e-b72e4e1c8c9e
target_node_id (empty) 9fe05a75-6726-4be8-b578-0058603267a6
create Caio AlmeidarecommendsApollo GraphQL
context (empty) Highlighted for per-field metrics and schema documentation.
relation (empty) recommends
source_node_id (empty) 8e94e35e-1e33-48c7-ac3e-b72e4e1c8c9e
target_node_id (empty) cebd5aab-3634-4afe-b0a8-ba8fb96ddffc
create Caio AlmeidarecommendsGraphQL performance regression tests
context (empty) Advocates assert_queries-based tests to catch N+1 before production.
relation (empty) recommends
source_node_id (empty) 8e94e35e-1e33-48c7-ac3e-b72e4e1c8c9e
target_node_id (empty) da77f6d8-91f0-429d-8103-27a13e6ba3de

Read set

68 nodes

talk Optimizing performance in Rails apps with GraphQL layer search_nodes+get_node_edges talk Better WebPerformance with Rails search_nodes talk LATERAL Joins Rails Performance Lightning Talk search_nodes concept RAIL Performance Model search_nodes tool ViewComponent search_nodes concept Performance Time Budget search_nodes resource The Rails and Hotwire Codex search_nodes talk Sonic Pi Music Performance search_nodes concept Static Page Caching via nginx search_nodes tool GraphQL search_nodes takeaway Name Things To Find Their Properties search_nodes concept Retrieval Augmented Generation search_nodes concept AI Agent search_nodes project Ruby News search_nodes talk Events events events search_nodes tool ChatGPT search_nodes tool langchainrb search_nodes tool SXG Validator search_nodes concept xkcd Dependency / Nebraska Problem search_nodes concept Vector Database search_nodes tool RealtimeBoard search_nodes tool Midjourney search_nodes takeaway Be kind and build useful things search_nodes resource awesome-ddd search_nodes project Nerds and Threads search_nodes event wroclove.rb 2024 search_nodes event wroclove.rb 2022 search_nodes event wroclove.rb 2023 search_nodes event wroclove.rb 2025 search_nodes event wroclove.rb 2026 search_nodes event wroclove.rb 2019 search_nodes event wroclove.rb 2018 search_nodes talk Mutation testing workshop wroclove.rb 2019 search_nodes talk Webmock unmocked search_nodes talk One machine please, make it Turing search_nodes concept N+1 Queries search_nodes question Aren't query optimizations a better first step than caching? search_nodes concept Flat Query Structure search_nodes takeaway Prefer LATERAL over CTE for filtered top-N per group search_nodes takeaway Read models must not depend on each other search_nodes question Should touch on belongs_to be avoided in complex apps? search_nodes takeaway Use Immediate Transactions for Rails search_nodes concept destroy_all vs delete_all search_nodes concept LATERAL join search_nodes person Caio Almeida search_nodes project Ruby Romania search_nodes concept DNS geolocation routing search_nodes person Adam Okoń search_nodes tool Prometheus search_nodes resource Rocket Real-Time Benchmark search_nodes tool Datadog search_nodes tool Grafana search_nodes tool New Relic search_nodes tool Codecov search_nodes takeaway Sign serverlessforruby.org petition search_nodes takeaway Trailblazer tracing saves thousands of debugging hours search_nodes concept Distributed Monolith search_nodes takeaway Graph resolvers compute minimal API calls automatically search_nodes tool Falcor search_nodes tool Pathom search_nodes question JSON API or GraphQL — what do you recommend? search_nodes project AnyCable search_nodes concept GitHub Self-Hosted Runner search_nodes takeaway Contribute to Arkency aggregates repository search_nodes tool Ruby search_nodes tool JSON API Resources search_nodes project granite search_nodes tool Representable search_nodes

2 edges