In Neon, point-in-time restores are instant—even for 100 TB databases. See how it compares to AWS RDS
Docs/Neon Auth/Tutorial

Neon Auth Tutorial

beta

See how Neon Auth eliminates the complexity of manual user data synchronization, making your development faster and your applications more robust.

Beta

Neon Auth is in beta and ready to use. We're actively improving it based on feedback from developers like you. Share your experience in our Discord or via the Neon Console.

Modern application development is becoming increasingly reliant on third-party authentication providers like Clerk, Stack Auth, etc., to handle secure user management. While these platforms excel at streamlining login workflows and protecting sensitive data, developers frequently encounter a hidden challenge: maintaining parity between external identity records and their application's database.

Profile updates, role changes, and user deletions in your authentication service don’t automatically reflect in your application’s data layer. Today, developers typically address this gap through several approaches:

  • Webhooks: Many providers offer real-time event notifications (e.g., user.updated) to trigger immediate updates in your system.
  • Polling: Periodically querying the auth provider’s API checks for changes, but this approach introduces latency and risks hitting rate limits.
  • Login-time sync: Fetching fresh profile data during authentication ensures accuracy for active users at the expense of increased latency while also leaving stale data for inactive accounts.

While these methods partially mitigate the problem, they often require writing custom synchronization scripts, implementing brittle listeners, and manually reconciling data discrepancies – turning a theoretical time-saver into an ongoing maintenance burden.

Neon Auth offers a streamlined solution to this common challenge. Instead of grappling with complex synchronization methods, Neon Auth automatically synchronizes user profiles directly from your authentication provider to your Neon Postgres database. This eliminates the need for manual updates, ensuring accurate, real-time data. You gain the benefits of efficient, automated user data management while retaining complete control over your core application information

note

Currently, Neon Auth is available for use with Stack Auth, with support for additional authentication providers coming soon.

A typical user data synchronization scenario

To illustrate the benefits of Neon Auth, let’s consider a common scenario where you need to synchronize user data between your authentication provider and your application’s database.

Scenario overview

You are building a social media platform where users can create profiles, post content, and interact with others. You use Clerk as your authentication provider to handle user registration, login, and password management. Your application’s database stores user profiles, posts, comments, and other social data.

Data synchronization requirements

  • User profiles: When a user registers or updates their profile on Clerk, you need to synchronize their profile data to your application’s database. This includes user ID, name, email, profile picture, and other relevant information.

  • User deletion: If a user deletes their account, you must remove their profile and associated data from your application’s database.

  • Data consistency: Ensure that user data in your application’s database remains consistent with the latest information from Clerk. Any changes to user profiles should reflect immediately in your database.

Challenges with manual synchronization

Without Neon Auth, you would typically address these requirements using manual synchronization methods like webhooks, polling, or login-time sync. However, these approaches introduce several challenges:

Typical User Data Synchronization Challenges

  • Infrastructure and maintenance burden: Setting up and maintaining a robust synchronization system manually involves significant infrastructure overhead. This includes configuring secure webhook endpoints, managing job queues for retries and background processing, and deploying worker processes – all adding to operational complexity. Consider the example of a webhook handler, demonstrating just a fraction of the code needed for basic user synchronization and validation:

    // Webhook handler for a `user.created` event
    
    import { WebhookEvent, UserJSON } from '@clerk/nextjs/server';
    import { headers } from 'next/headers';
    import { Webhook } from 'svix';
    import { db } from '@/app/db/server';
    import { User, users } from '@/app/schema';
    
    const webhookSecret = process.env.CLERK_WEBHOOK_SECRET || '';
    
    async function validateRequest(request: Request) {
      const payloadString = await request.text();
      const headerPayload = await headers();
    
      const svixHeaders = {
        'svix-id': headerPayload.get('svix-id')!,
        'svix-timestamp': headerPayload.get('svix-signature')!,
        'svix-signature': headerPayload.get('svix-signature')!,
      };
      const wh = new Webhook(webhookSecret);
      return wh.verify(payloadString, svixHeaders) as WebhookEvent;
    }
    
    export async function POST(request: Request) {
      const payload = await validateRequest(request);
      const payloadData = payload.data as UserJSON;
      const user = {
        userId: payload.data.id,
        name: `${payloadData.first_name} ${payloadData.last_name}`,
        email: payloadData.email_addresses[0].email_address,
      } as User;
      await db.insert(users).values(user);
      return Response.json({ message: 'User added' });
    }

    Complexity Multiplies with Event Types

    Crucially, this code only handles a single event: user.created. To achieve complete synchronization, you would need to write separate webhook handlers for user.updated, user.deleted, and potentially other event types (like role changes, email updates, profile changes, etc.), depending on your application's needs and the capabilities of your auth provider. Each new webhook handler multiplies the complexity of your synchronization system and introduces more potential points of failure. This quickly becomes a brittle and unwieldy system where, inevitably, everything that is bound to fail will fail.

  • Development overhead: Building custom synchronization logic requires significant development effort. You need to write code for event parsing, data mapping, database updates, and complex error handling. Polling and login-time sync, while alternatives, introduce their own complexities in terms of rate limit management, latency, and data consistency.

  • Query inefficiency: Without synchronized data, applications often resort to fetching user data from the auth provider API at runtime, leading to increased latency and complex queries. This dependency on external APIs can impact performance and reliability.

  • Data Inconsistency risks: Manual synchronization methods are inherently prone to inconsistencies. Webhook failures, polling delays, or errors in custom logic can lead to your database containing stale or inaccurate user data, potentially causing application errors and data integrity issues.

Streamlining user data sync

Neon Auth offers a streamlined solution to these challenges by automating user data synchronization. Let’s examine how Neon Auth simplifies the process and eliminates the complexities associated with manual methods.

Simplified Architecture

Neon Auth introduces a simplified architecture that removes the need for webhooks, polling, and custom synchronization scripts. As shown in the diagram below, Neon Auth acts as an intermediary layer that automatically synchronizes user data from your authentication provider to your Neon Postgres database.

How Neon Auth Simplifies User Data Synchronization

With Neon Auth, the architecture is significantly cleaner and more efficient:

  • Automated synchronization: Neon Auth handles the entire synchronization process automatically in the background. You no longer need to set up and maintain complex synchronization logic.
  • No webhooks or polling: No need to develop and maintain webhook endpoints for different user events (e.g., user.created, user.updated, user.deleted). Neon Auth automatically syncs user data changes to your database without requiring external triggers.
  • Direct database access: Your application can directly query user data from the neon_auth.users_sync table in your Neon Postgres database. This simplifies data access and improves query performance.
  • Error handling and retries: Neon Auth includes built-in error handling and retry mechanisms to ensure data consistency without requiring custom code.

Enhanced data consistency

Neon Auth ensures enhanced data consistency by providing a reliable and automated synchronization mechanism. Neon Auth continuously monitors for user data changes in your authentication provider and automatically synchronizes these changes to your Neon Postgres database.

Get started with Neon Auth

Watch the following video to see how Neon Auth simplifies user data synchronization:

Accessing synchronized user data

With Neon Auth, accessing synchronized user data becomes incredibly straightforward. You can directly query the neon_auth.users_sync table within your Neon Postgres database.

Neon Auth automatically creates and manages this table, populating it with user data from your connected authentication provider. The table schema including the following columns:

  • id: The unique user ID from your authentication provider.
  • name: The user's display name.
  • email: The user's email address.
  • created_at: Timestamp of user creation in the auth provider.
  • updated_at: Timestamp of the last user profile update.
  • deleted_at: Timestamp indicating user deletion (if applicable).
  • raw_json: A JSON column containing the full raw user data received from the authentication provider.

You can query this table using standard SQL, just like any other table in your Postgres database.

Example Query:

To retrieve all user information, you can use a simple SELECT statement:

SELECT * FROM neon_auth.users_sync;

This query will return a result set similar to the example below:

idnameemailcreated_atupdated_atdeleted_atraw_json
d37b6a30...Jordan Riverajordan@company.co2025-02-12 19:44...nullnull{"id": "d37b6a30...", ...}
0153cc96...Alex Kumaralex@acme.com2025-02-12 19:44...nullnull{"id": "0153cc96...", ...}
51e491df...Sam Patelsam@startup.dev2025-02-12 19:43...2025-02-12 19:46...null{"id": "51e491df...", ...}

Efficient queries with JOINs: You can easily join user data with other application tables to build complex queries. For example, to retrieve posts along with the author's name, you can use a simple JOIN statement:

SELECT posts.*, neon_auth.users_sync.name AS author_name
FROM posts
JOIN neon_auth.users_sync ON posts.author_id = neon_auth.users_sync.id;

Conclusion

Neon Auth streamlines user data synchronization, replacing cumbersome manual methods with an automated, efficient solution. This simplifies development, accelerates query performance, ensures data consistency, and minimizes infrastructure costs.

By leveraging Neon Auth, you can focus on building your application's core features while leaving the complexities of user data management to Neon.

Last updated on

Was this page helpful?