Stripe Subscriptions SQL Template

SQL table creation template for syncing Stripe subscription data to your PostgreSQL database.

Updated: 15 Dec 2025

Stripe Subscriptions SQL Template

Create a database table to store Stripe subscription data including recurring billing details and subscription lifecycle status.

What Data is Synced?

The Stripe Subscriptions sync captures essential subscription information from your Stripe account:

  • Subscription ID: Unique Stripe subscription identifier
  • Customer Reference: Which customer owns the subscription
  • Description: Optional user-provided description
  • Status Information: Current subscription status (active, canceled, past_due, etc.)
  • Billing Cycle Details: Current period start/end dates, cancellation flags and timestamps
  • Payment Information: Currency and default payment method
  • Livemode Flag: Whether this is a live or test mode subscription
  • Timestamps: When the subscription was created, canceled, or ended
  • Complete Subscription Data: Full Stripe subscription object stored as JSONB
  • Sync Tracking: Timestamp of when CLS last synced this record

SQL Table Template

Table Schema Explanation

Here's what each column in the table represents:

ColumnTypeDescription
idTEXTStripe subscription ID (e.g., sub_abc123). Primary key.
customerTEXTStripe customer ID who owns this subscription (e.g., cus_xyz789). Required.
statusTEXTSubscription status: active, canceled, incomplete, incomplete_expired, past_due, trialing, or unpaid. Required.
descriptionTEXTOptional user-provided description for the subscription.
current_period_startTIMESTAMPTZTimestamp when the current billing period started.
current_period_endTIMESTAMPTZTimestamp when the current billing period ends.
cancel_at_period_endBOOLEANWhether the subscription will cancel at the end of the current period. Defaults to false.
canceled_atTIMESTAMPTZTimestamp when subscription was canceled. Null if not canceled.
ended_atTIMESTAMPTZTimestamp when subscription ended. Null if still active.
currencyTEXTThree-letter ISO currency code (e.g., usd, gbp, eur).
default_payment_methodTEXTDefault payment method ID for this subscription.
dataJSONBComplete Stripe subscription object stored as JSON.
livemodeBOOLEANWhether this is a live mode subscription (true) or test mode (false). Required.
createdTIMESTAMPTZTimestamp when subscription was created in Stripe.
synced_atTIMESTAMPTZTimestamp when CLS last synced this subscription record. Auto-updated.

The status field is crucial for understanding subscription lifecycle. Most active revenue comes from subscriptions with status = 'active' or status = 'trialing'.

Usage Examples

After syncing, you can query your subscription data using standard SQL:

-- Get all active subscriptions
SELECT * FROM stripe_subscriptions
WHERE status = 'active';

-- Find subscriptions ending in the next 7 days
SELECT
  id,
  customer,
  current_period_end AS period_ends
FROM stripe_subscriptions
WHERE status = 'active'
  AND current_period_end BETWEEN NOW() AND NOW() + INTERVAL '7 days';

-- Count subscriptions by status
SELECT
  status,
  COUNT(*) AS count
FROM stripe_subscriptions
GROUP BY status
ORDER BY count DESC;

-- Find subscriptions scheduled to cancel
SELECT * FROM stripe_subscriptions
WHERE cancel_at_period_end = true
  AND status = 'active';

-- Get subscriptions currently in trial
SELECT
  id,
  customer,
  data->>'trial_start' AS trial_started,
  data->>'trial_end' AS trial_ends
FROM stripe_subscriptions
WHERE status = 'trialing';

-- Find recently canceled subscriptions (last 30 days)
SELECT * FROM stripe_subscriptions
WHERE canceled_at > NOW() - INTERVAL '30 days'
ORDER BY canceled_at DESC;

-- Get subscriptions by currency
SELECT * FROM stripe_subscriptions
WHERE currency = 'usd'
  AND status = 'active';

Common Customizations

The template includes performance indexes for customer, status, and livemode columns. You can add additional table-specific customizations:

Add Index for Period End Date Queries

CREATE INDEX idx_stripe_subscriptions_period_end
ON stripe_subscriptions(current_period_end);

Add Index for Currency Filtering

CREATE INDEX idx_stripe_subscriptions_currency
ON stripe_subscriptions(currency);

Add Computed Column for Active Revenue

ALTER TABLE stripe_subscriptions
ADD COLUMN is_revenue_generating BOOLEAN
GENERATED ALWAYS AS (status IN ('active', 'trialing')) STORED;

Subscription Status Explained

Understanding subscription statuses is key to working with this data:

StatusDescription
activeSubscription is paid and active
trialingCurrently in free trial period
past_duePayment failed; awaiting payment
canceledSubscription has been canceled
unpaidPayment failed and retries exhausted
incompleteInitial payment incomplete
incomplete_expiredIncomplete payment expired

Revenue-generating subscriptions typically have status active or trialing. Use these statuses for calculating Monthly Recurring Revenue (MRR) and other business metrics.