Skip to main content

What Are Quotas?

Quotas are monthly limits on the number of events you can send through PingPilot. Every plan has a quota that resets on the 1st of each month.
Quotas ensure fair usage and help maintain system performance for all users.

Quota Limits by Plan

PlanEvents per MonthEvent Categories
Free1003
Pro1,00010
Enterprise10,000100
These limits are defined in quota.ts:
export const FREE_QUOTA = {
  maxEventsPerMonth: 100,
  maxEventCategories: 3,
} as const

export const PRO_QUOTA = {
  maxEventsPerMonth: 1000,
  maxEventCategories: 10,
} as const

export const ENTERPRISE_QUOTA = {
  maxEventsPerMonth: 10000,
  maxEventCategories: 100,
} as const

How Quotas Work

Monthly Reset

Your quota resets automatically on the 1st day of each month at midnight UTC. This gives you a fresh allocation of events.

Event Counting

Every successful event sent via the API counts toward your monthly quota:
  1. You send an event via POST /api/v1/event
  2. The API checks your current usage
  3. If under the limit, the event is processed
  4. Your quota counter increments by 1
  5. Event is delivered to Discord, Telegram, and email

Quota Tracking

The quota system is stored in your database and tracked per user, per month:
model Quota {
  id     String @id @default(cuid())
  user   User   @relation(fields: [userId], references: [id])
  userId String @unique

  year  Int
  month Int
  count Int @default(0)

  updatedAt DateTime @updatedAt
}
See schema.prisma:85-95 for the full model.

Quota Enforcement

When you reach your monthly limit, the API will reject new events:

API Response

HTTP/1.1 429 Too Many Requests
Content-Type: application/json

{
  "message": "Monthly quota reached. Please upgrade your plan for more events"
}

Implementation

The quota check happens before event processing in route.ts:84-99:
const quotaLimit =
  user.plan === "FREE"
    ? FREE_QUOTA.maxEventsPerMonth
    : user.plan === "PRO"
    ? PRO_QUOTA.maxEventsPerMonth
    : ENTERPRISE_QUOTA.maxEventsPerMonth

if (quota && quota.count >= quotaLimit) {
  return NextResponse.json(
    {
      message:
        "Monthly quota reached. Please upgrade your plan for more events",
    },
    { status: 429 }
  )
}

Monitoring Your Quota

Dashboard View

Your dashboard displays:
  • Current usage: How many events you’ve sent this month
  • Quota limit: Your total monthly allowance
  • Remaining events: How many events you can still send
  • Reset date: When your quota will reset

Programmatic Monitoring

You can track quota usage by monitoring 429 responses from the API:
const response = await fetch('https://api.pingpilot.com/api/v1/event', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(eventData)
})

if (response.status === 429) {
  console.log('Quota exceeded - upgrade plan or wait for reset')
}

Quota Updates

After each successful event, the quota counter is updated atomically:
await db.quota.upsert({
  where: { userId: user.id, month: currentMonth, year: currentYear },
  update: { count: { increment: 1 } },
  create: {
    userId: user.id,
    month: currentMonth,
    year: currentYear,
    count: 1,
  },
})
This implementation at route.ts:198-207 ensures:
  • Atomic increments: No race conditions
  • Automatic creation: First event of the month creates the quota record
  • Accurate tracking: Count matches actual events processed

What Counts Toward Quota

Counts Toward Quota

  • Successful API calls to /api/v1/event
  • Events with DELIVERED status
  • All event notifications sent

Does NOT Count

  • Failed API calls (400, 401, 403, 422, 500)
  • Events that fail validation
  • Dashboard page views
  • API key generation
Even if event delivery fails (Discord/Telegram/Email), the event still counts toward your quota because it was successfully received and processed by the API.

Managing Your Quota

Best Practices

  1. Monitor usage regularly: Check your dashboard to avoid surprises
  2. Implement retry logic carefully: Failed requests don’t count, but be mindful of retries
  3. Plan ahead: If you’re approaching your limit, upgrade before you hit it
  4. Use categories wisely: Organize events to make the most of your category limit

When to Upgrade

Consider upgrading from Free to Pro if:
  • You’re consistently using 80%+ of your 100 events
  • You need more than 3 event categories
  • You’re using PingPilot for production apps
  • You need priority support
View Pro plan →

Quota FAQs

The API will return a 429 Too Many Requests response and reject the event. You’ll need to either wait until the 1st of next month when your quota resets, or upgrade to a higher plan.
No. Only successfully processed events count toward your quota. If the API returns an error before processing (like 400, 401, 422), it doesn’t count.
Currently, no. Each plan has a fixed monthly quota. If you need more events, you’ll need to upgrade to the next plan tier.
Quota resets happen on the 1st of each month at midnight UTC, regardless of your local timezone.
No. Unused events don’t roll over to the next month. Your quota resets to 0 on the 1st of each month.
Plan upgrades are instant. As soon as your payment is confirmed through Stripe, your new quota limits are active.

Technical Details

Database Schema

Quotas are tracked in the Quota table with a composite key on userId, month, and year. This allows efficient lookups and automatic monthly isolation.

Performance

The quota check is optimized for low latency:
  1. Single database query to fetch current quota
  2. In-memory comparison against plan limits
  3. Fast rejection if limit exceeded
  4. Atomic increment after successful event processing

Accuracy

The system uses database transactions and atomic operations to ensure quota counts are always accurate, even under concurrent load.
The quota enforcement logic is battle-tested and handles race conditions correctly using database-level atomic operations.

Build docs developers (and LLMs) love