AWS AppSync EU Alternative 2026: GraphQL Subscriptions, GDPR, and the Resolver Chain Under US Jurisdiction
Post #775 in the sota.io EU Compliance Series
AWS AppSync is Amazon's managed GraphQL service. It lets you build real-time APIs without managing WebSocket servers, write resolver logic without running Node.js clusters, and connect your frontend directly to DynamoDB, Lambda, RDS, Elasticsearch, or any HTTP endpoint — all through a single, typed GraphQL schema. For teams already on AWS, AppSync removes an entire tier of infrastructure complexity. The managed real-time subscriptions feature alone eliminates thousands of lines of WebSocket management code.
GraphQL's expressive query model is both its strength and its GDPR risk surface. In a REST API, the shape of a response is fixed by the server. In GraphQL, clients specify exactly which fields they need. A client can request user { id email address { street city postcode } purchaseHistory { orderId amount items { productId quantity } } } in a single query. The same query that makes your frontend efficient also creates a single, structured request that names every personal data field your application cares about — and that request travels through AppSync's managed infrastructure under US jurisdiction.
Amazon Web Services, Inc. is a Delaware corporation subject to the CLOUD Act (18 U.S.C. § 2713). Every GraphQL query, mutation, and subscription that flows through AppSync passes through Amazon-controlled infrastructure. Every resolver that executes — whether it calls DynamoDB, Lambda, RDS, or an external HTTP source — is orchestrated by AppSync's managed engine. The field-level logs that AppSync optionally writes to CloudWatch capture the arguments and response data from each resolver call. These logs are personal data, and they live under US jurisdiction.
The Resolver Chain: CLOUD Act Jurisdiction Follows the Data Flow
AppSync's resolver model is its most powerful and most complex feature. When a GraphQL query arrives at AppSync, the service breaks it down into individual field resolutions. Each field in your schema has a resolver that defines how to fetch the data — a DynamoDB table, a Lambda function, a direct HTTP call, or AppSync's own pipeline resolver syntax.
This resolver chain means that a single GraphQL query can trigger a cascade of data operations across multiple AWS services. A query for customerOrder might:
- Call a Lambda function to validate authentication context (Lambda: personal data under US jurisdiction)
- Query a DynamoDB table for the order record (DynamoDB: personal data under US jurisdiction)
- Call another Lambda function to fetch the customer's address for shipping display (Lambda + DynamoDB: personal data under US jurisdiction)
- Query an RDS database for product catalog information joined to order line items (RDS: personal data under US jurisdiction)
- Call an external HTTP endpoint for real-time inventory status (HTTP: metadata under US jurisdiction)
Each step in this chain is orchestrated by AppSync. AppSync receives the intermediate results, passes them between resolvers, and assembles the final response. The AppSync service — operating on Amazon's infrastructure — touches every piece of data that flows through the resolution chain.
The CLOUD Act implication: A compelled disclosure order served on Amazon does not need to target any specific data source. The order can compel AppSync-level logs, which capture the inputs and outputs of every resolver execution. These resolver logs contain the arguments passed to each resolver (often personal data: user IDs, email addresses, query filters) and the response data returned (order details, customer records, payment summaries). AppSync resolver logs are a comprehensive record of every API call that has touched personal data across your entire system.
Article 5(1)(c) data minimization tension: GraphQL is architecturally designed for clients to request exactly the data they need — no more. This aligns with GDPR's data minimization principle at the application layer. But the resolver chain executes at the infrastructure layer, and AppSync's execution model does not enforce minimization at the network level. Even when a client requests only { user { email } }, the Lambda resolver that AppSync invokes may fetch the full user record from DynamoDB — including fields the client never asked for. The minimization is enforced by application code, not by AppSync's infrastructure. AppSync logs capture what the resolver fetched, not what the client requested.
Real-Time Subscriptions: Long-Lived Connections as Behavioral Data
AppSync's real-time subscription feature is one of its most compelling capabilities. Clients connect to AppSync over WebSocket (using the MQTT protocol over WebSockets) and receive push notifications when data matching their subscription filter changes. A subscription like onOrderStatusChanged(customerId: "eu-user-123") keeps a persistent connection open and delivers notifications whenever that customer's order status updates.
This subscription model creates a category of behavioral data that is distinct from transactional data. When a client subscribes to AppSync, Amazon knows:
- That a specific device or session is interested in a specific customer's data
- How long the subscription connection remains open (session duration)
- The subscription filter parameters (which data the client is tracking)
- Connection and disconnection events (application lifecycle patterns)
AppSync manages WebSocket connections at Amazon's infrastructure layer. Connection metadata — connection IDs, filter parameters, connection duration, reconnection patterns — is processed by Amazon's managed WebSocket infrastructure. This metadata is logged in CloudWatch and accessible through AppSync's monitoring API.
The profiling risk under GDPR Article 4(4): Subscription patterns are behavioral data. A healthcare application where clients subscribe to onPatientVitalChanged reveals which clinical users are monitoring which patients in real time. A financial application where clients subscribe to onAccountTransactionCreated(accountId: "...") reveals which account holders are actively monitoring specific accounts. The subscription filter parameters identify not just that a user is active, but what data they care about at this moment. Over time, subscription history constitutes a behavioral profile of how users interact with sensitive data.
AppSync's subscription connection events are not optional. When you use AppSync real-time subscriptions, Amazon's infrastructure manages the WebSocket layer. You cannot intercept, sanitize, or prevent the logging of subscription metadata at the AppSync infrastructure level. The behavioral data exists in Amazon's systems as a consequence of using the service.
Article 25 GDPR (Data Protection by Design and by Default): AppSync's subscription model does not offer a data-protection-by-design alternative for teams who want real-time APIs without behavioral metadata collection. The connection infrastructure is Amazon's, and the metadata belongs to Amazon's logging systems. For EU organizations processing special category data (healthcare, financial, legal), this subscription metadata may itself constitute special category data under Article 9 if subscription filter parameters reveal health conditions, financial situations, or legal proceedings.
Field-Level Logging: Personal Data in Your CloudWatch Logs
AppSync offers configurable logging levels. At the lowest level, AppSync logs only request-level metadata (operation name, latency, HTTP status). At the highest level — "ALL" logging — AppSync logs the complete execution trace: every resolver's input arguments and output response.
For developers, field-level logging is invaluable for debugging. When a resolver returns unexpected data, the logs show exactly what each step of the resolution chain received and produced. But for GDPR compliance, field-level logging creates a systematic record of personal data flowing through every AppSync operation.
Consider a mutation like updatePatientRecord(patientId: "patient-456", diagnosis: "F32.1", treatment: "SSR-regime-2"). With field-level logging at ANY level above NONE, AppSync logs the operation name. With FIELD_ERRORS logging, AppSync logs resolver errors which may include argument values. With ALL logging, AppSync logs the complete resolver input — including patientId, diagnosis, and treatment — to CloudWatch.
CloudWatch log groups are stored in the AWS region you specify. But CloudWatch, like AppSync itself, is an AWS service operated by Amazon Web Services, Inc. — a Delaware corporation. The choice of EU region affects data residency, not CLOUD Act jurisdiction. A CloudWatch log group in eu-west-1 is still accessible to Amazon and subject to CLOUD Act compelled disclosure.
The default logging behavior: AppSync does not enable logging by default. But when development teams enable logging for debugging — a routine and expected practice — they may not consider that field-level logs contain personal data. The logs persist until a retention policy is set. Without an explicit CloudWatch log group retention policy, AppSync logs accumulate indefinitely, creating an ever-growing archive of personal data under US jurisdiction.
Article 30 GDPR (Records of Processing Activities): If AppSync field-level logging is enabled, the CloudWatch log groups constitute a record of processing activity that must be documented in the organization's Article 30 register. The log groups are not typically considered a "system" by development teams — they are infrastructure logging — but under GDPR they are a data store containing personal data, subject to all the obligations that apply to any other data store: retention limits, access controls, data subject request handling, and DPA documentation with Amazon.
Caching and Erasure: The AppSync Cache Layer
AppSync offers a server-side caching feature that caches resolver responses at the AppSync layer. When caching is enabled, AppSync stores resolver outputs in an ElastiCache-backed cache. Subsequent requests with the same query parameters receive the cached response without executing resolvers.
This caching layer creates an erasure problem that is structurally similar to the ElastiCache and DAX cache problems documented elsewhere in this series. When a data subject exercises their Article 17 right to erasure, the erasure must reach every copy of their data. If AppSync caching is enabled, cached resolver responses may contain the data subject's personal data. Erasing the record from DynamoDB, RDS, or the backing data source does not automatically invalidate AppSync cache entries that contain that data.
AppSync's cache invalidation mechanism requires explicit API calls or TTL expiration. For an erasure request, the organization must:
- Identify which AppSync operations could cache the data subject's data
- Determine what cache keys correspond to that data subject
- Issue explicit cache invalidation calls for each relevant cache key
- Wait for TTL expiration for any cache entries that cannot be explicitly invalidated
This process is operationally complex and difficult to automate reliably. Cache keys are derived from query parameters, which vary by query type. A customer's data might be cached under their customer ID, their email, their phone number, or a combination of filter parameters — depending on which queries have been executed since the last cache flush.
Practical risk: Development teams that enable AppSync caching for performance are unlikely to have documented this as a data store in their Article 30 register or considered it in their erasure procedures. The AppSync cache is invisible infrastructure — it speeds up your API transparently. But it is a data store under GDPR, subject to the same obligations as any other system that holds personal data.
Authorization and Identity: Cognito Under US Jurisdiction
AppSync supports four authorization modes: API Key (stateless, no identity), IAM authorization (AWS Signature v4), Amazon Cognito User Pools, and Lambda custom authorizers. Most production applications use Cognito User Pools for user authentication — AppSync validates JWT tokens issued by Cognito and uses Cognito identity claims to authorize GraphQL operations.
The Cognito integration means that AppSync's authorization context includes personal data from Cognito: user IDs, email addresses, group memberships, and custom attributes. AppSync receives this identity data on every authenticated request and makes it available to resolvers through the $ctx.identity context object. This data is logged in AppSync's request logs.
Cognito User Pools is itself an Amazon service operating under US jurisdiction. The combination of Cognito (identity management) and AppSync (API layer) means that two AWS services, both under CLOUD Act jurisdiction, jointly process the full context of every authenticated user interaction: who the user is (Cognito) and what data they requested (AppSync).
The Lambda authorizer alternative: AppSync supports Lambda custom authorizers, which allow organizations to implement their own authorization logic — potentially using EU-hosted identity providers (Keycloak, Auth0 EU, Authentik) instead of Cognito. A Lambda authorizer receives the authorization token, calls an external IdP to validate it, and returns authorization context to AppSync. But the Lambda authorizer runs on AWS Lambda — still under US jurisdiction. AppSync receives the authorization context, including any personal data the authorizer returns. The CLOUD Act exposure is reduced at the identity management layer (if using EU IdP instead of Cognito) but not at the AppSync orchestration layer.
EU-Native GraphQL Alternatives for 2026
The good news for EU development teams is that GraphQL is an open specification. The managed convenience of AppSync is valuable, but every AppSync feature — schema validation, resolver execution, real-time subscriptions, caching, authorization — can be implemented on EU infrastructure using open-source tooling.
Hasura
Hasura is the closest functional equivalent to AppSync in the EU-hosted landscape. It provides:
- Automatic GraphQL API generation from PostgreSQL, MS SQL Server, or MongoDB schemas
- Real-time subscriptions via database triggers and polling
- Row and column-level authorization rules defined in a declarative permission system
- Remote Schema federation (equivalent to AppSync's HTTP resolvers)
- Actions (custom resolvers backed by HTTP endpoints or serverless functions)
Hasura is fully open source (Apache 2.0). You can deploy it on EU infrastructure — a Hetzner VM, a self-managed Kubernetes cluster, or any EU-hosted container platform — and the PostgreSQL backend can run in the same datacenter. The subscription infrastructure is your own WebSocket server, not Amazon's. The resolver logs are in your own log management system (Loki, Elasticsearch running in the EU), not CloudWatch.
For organizations already using PostgreSQL, Hasura's schema introspection means you can expose your existing data model as a GraphQL API in minutes. For teams with complex business logic requirements, Hasura's Actions feature allows custom resolvers backed by HTTP microservices — equivalent to AppSync's Lambda resolvers, but pointing to EU-hosted services.
Deployment: Hasura runs as a single Docker container. On Hetzner or OVH, a Hasura instance with PostgreSQL backend can serve hundreds of concurrent subscriptions on a €20/month VM. For high-availability, Hasura supports horizontal scaling behind a load balancer with shared Redis for subscription state.
PostGraphile
PostGraphile generates a GraphQL API automatically from a PostgreSQL schema. It is more database-centric than Hasura — PostGraphile translates every GraphQL query directly into optimized SQL, executing the entire query in a single database round-trip using PostgreSQL's JSON aggregation features.
For EU organizations whose data model is primarily PostgreSQL, PostGraphile offers:
- Zero separate resolver infrastructure — all logic runs in PostgreSQL functions, triggers, and row-level security policies
- GDPR-native access control through PostgreSQL's role system and row-level security
- Subscription support via PostgreSQL LISTEN/NOTIFY
- Plugin system for custom business logic
The data-protection advantage of PostGraphile is structural: the GraphQL layer is a thin translation layer over PostgreSQL. Authorization rules enforced at the PostgreSQL level apply to all access paths — GraphQL, direct SQL, and migration scripts — not just the GraphQL API. The audit trail is PostgreSQL's transaction log, not a separate managed service's access logs.
WunderGraph
WunderGraph is an open-source API gateway that provides a BFF (Backend for Frontend) layer combining REST APIs, GraphQL APIs, and gRPC services into a single, TypeScript-first API layer. WunderGraph compiles your API definition to optimized network calls and handles caching, authentication, and real-time subscriptions at the gateway layer.
For teams building from existing REST APIs rather than greenfield GraphQL schemas, WunderGraph offers a migration path: wrap existing EU-hosted REST services in a GraphQL-compatible interface without requiring GraphQL servers on the backend. The WunderGraph gateway runs on EU infrastructure; the backing services are whatever you already have.
Directus
Directus is an open-source data platform that exposes any SQL database through both a REST API and a GraphQL API, with a built-in admin interface for non-technical users. For content-heavy applications where data editors need a CMS-like interface and developers need a GraphQL API, Directus provides both.
Directus is AGPL-3.0 licensed, with a commercial cloud offering and self-hosted deployment documentation. The GraphQL API is generated from your Directus collection (table) definitions, with fine-grained per-field access controls manageable through the admin UI. For EU organizations, Directus can be self-hosted on any EU-compliant infrastructure.
pg_graphql (Supabase)
pg_graphql is a PostgreSQL extension that exposes a GraphQL API directly from PostgreSQL's schema. It runs inside the PostgreSQL process, translating GraphQL queries to SQL without any external process. Supabase uses pg_graphql as the GraphQL layer in its managed Postgres product.
For EU teams already evaluating Supabase EU region deployments, pg_graphql provides a native GraphQL interface with the same data sovereignty guarantees as the underlying Postgres instance. If you run PostgreSQL on EU infrastructure, pg_graphql runs alongside it — no additional managed service, no external network calls for resolver execution.
Architecture Decision Framework
Choosing a GraphQL backend for EU compliance involves three distinct trade-off axes:
Schema ownership vs. convention: AppSync, Hasura, and PostGraphile all generate APIs from schemas or database structures. WunderGraph and custom GraphQL servers (Apollo Server, GraphQL Yoga) give you full schema control. For rapidly evolving data models, schema-first tools require more schema maintenance but offer stronger API contracts. For teams prioritizing development velocity on an existing database, Hasura and PostGraphile trade schema control for automatic API generation.
Subscription architecture: Real-time subscriptions are the most operationally complex feature to self-host. Hasura uses database polling and event triggers. PostGraphile uses PostgreSQL LISTEN/NOTIFY. WunderGraph uses server-sent events. Each approach has different scaling characteristics. AppSync's managed WebSocket infrastructure is operationally simpler, but the behavioral metadata it captures makes it a GDPR liability for sensitive applications.
Resolver complexity: Applications with complex business logic — multi-step authorization, computed fields, cross-service aggregation — require resolver infrastructure beyond simple database queries. Hasura's Actions and Remote Schemas, PostGraphile's PostgreSQL functions and plugins, and WunderGraph's TypeScript operation definitions each address this differently. Evaluate against your specific resolver complexity before committing to an architecture.
Migration Path from AppSync
If you are currently running AppSync and need to migrate for GDPR compliance, the migration path depends on your resolver architecture:
DynamoDB-backed resolvers: Migrate DynamoDB to PostgreSQL (using AWS DMS or manual export) and replace AppSync with Hasura or PostGraphile. The GraphQL schema can be preserved; only the resolver mapping changes. For applications where DynamoDB's flexibility is essential, Hasura supports DynamoDB sources in its Enterprise edition.
Lambda-backed resolvers: Migrate to Hasura Actions or WunderGraph Operations. Your Lambda functions become HTTP endpoint handlers called by the new GraphQL gateway. The Lambda code can often run unchanged on EU-hosted container platforms.
Subscriptions: Assess which subscriptions carry special category data (health, financial, behavioral). These are the highest priority for migration. Hasura subscriptions on EU PostgreSQL and PostGraphile LISTEN/NOTIFY are the most direct equivalents for data-change-driven notifications.
What GDPR Requires of Any GraphQL Backend
Whether you migrate to Hasura, PostGraphile, or another EU-hosted solution, GDPR obligations for a GraphQL API backend include:
Article 30 Records of Processing: Document the GraphQL API as a processing activity. Specify which personal data fields are exposed, for what purpose, under which legal basis, and with which retention period for query logs.
Article 25 Data Protection by Design: Configure field-level access controls so that the GraphQL schema enforces minimization at the API layer. A resolver for user { email } should not fetch and return user { email ssn medicalRecordId } even if the client did not request those fields. Use resolver-level access control (Hasura permissions, PostGraphile PostgreSQL roles) rather than relying on application-layer filtering.
Article 17 Erasure: Document every cache layer in your GraphQL stack — resolver caches, CDN edge caches, client-side Apollo cache or Relay store. Each cache layer must be addressable in an erasure workflow.
Article 32 Security: Enforce transport security (TLS) for all subscription WebSocket connections. Implement rate limiting at the GraphQL layer to prevent query complexity attacks that could expose disproportionate amounts of personal data through deeply nested queries.
Choosing EU Sovereignty for Your GraphQL Layer
The AppSync convenience trade-off is real. Managed WebSocket infrastructure, automatic VTL resolver execution, native DynamoDB integration, built-in field-level logging — AppSync removes weeks of infrastructure work. For a startup or small team building quickly on AWS, these trade-offs are easy to accept.
For EU organizations serving European users under GDPR, the trade-off calculation changes at scale. As your user base grows, the volume of personal data flowing through AppSync's managed infrastructure grows proportionally. The behavioral metadata in subscription connection logs, the personal data in field-level CloudWatch logs, the resolver execution records — all of this accumulates under US jurisdiction, subject to CLOUD Act compelled disclosure.
The EU-native alternatives — Hasura, PostGraphile, WunderGraph, Directus — have matured significantly over the past three years. Hasura in particular has closed most of the operational gap with AppSync: managed cloud offerings on EU infrastructure exist, the developer experience for schema design and resolver definition has improved substantially, and the subscription infrastructure is production-proven at scale.
The decision to use AppSync is a decision to process your users' behavioral data — their query patterns, their subscription interests, their real-time connection metadata — on US-controlled infrastructure. For European organizations whose users have legitimate expectations of data sovereignty, that decision requires explicit legal basis documentation, DPIA evaluation under Article 35, and ongoing governance that most development teams have not put in place.
Sota.io runs on EU infrastructure. Your application's GraphQL layer can too.
This post is part of the sota.io EU Compliance Series analyzing GDPR and CLOUD Act implications of commonly used cloud services. See also: AWS DynamoDB EU Alternative, AWS ElastiCache EU Alternative, AWS Lambda EU Alternative.
EU-Native Hosting
Ready to move to EU-sovereign infrastructure?
sota.io is a German-hosted PaaS — no CLOUD Act exposure, no US jurisdiction, full GDPR compliance by design. Deploy your first app in minutes.