Skip to main content

Overview

Monkeytype Premium enhances your typing experience with increased result storage, detailed activity tracking, and visual badges to show your support for the platform.
Premium features must be enabled server-wide by administrators. Check with your instance administrator to confirm availability.

Premium Benefits

1. Increased Result Limit

The most significant premium benefit is dramatically increased result storage.

Regular Users

1,000 resultsStandard result history for tracking your progress.

Premium Users

10,000 results10x more storage for comprehensive long-term analysis.
Technical Implementation: The limit is enforced in backend/src/api/controllers/result.ts:92-95:
const maxLimit =
  premiumFeaturesEnabled && userHasPremium
    ? req.ctx.configuration.results.limits.premiumUser  // 10,000
    : req.ctx.configuration.results.limits.regularUser; // 1,000
From backend/src/constants/base-configuration.ts:20-22:
limits: {
  regularUser: 1000,
  premiumUser: 10000,
}
If you exceed your result limit, older results are not automatically deleted. However, you won’t be able to retrieve results beyond your limit. Consider exporting your data periodically.

2. Test Activity History Access

Premium users gain access to their complete test activity history, showing:
  • Daily test counts for the entire year
  • Historical test activity data by year
  • Visualization-ready data for activity heatmaps
API Endpoint:
GET /users/testActivity

// Response format:
{
  "2024": [1, 3, 0, 5, 2, ...], // Tests per day (365 values)
  "2025": [2, 1, 4, ...]
}
From backend/src/api/controllers/user.ts:1238-1261:
export async function getTestActivity(
  req: MonkeyRequest,
): Promise<GetTestActivityResponse> {
  const premiumFeaturesEnabled = req.ctx.configuration.users.premium.enabled;
  const userHasPremium = await UserDAL.checkIfUserIsPremium(uid, user);

  if (!premiumFeaturesEnabled) {
    throw new MonkeyError(503, "Premium features are disabled");
  }

  if (!userHasPremium) {
    throw new MonkeyError(503, "User does not have premium");
  }

  return new MonkeyResponse(
    "Test activity data retrieved",
    user.testActivity ?? null,
  );
}
Non-premium users can still see their current test activity (last 372 days) via GET /users/currentTestActivity. Premium unlocks the full historical data.

3. Premium Badge

Premium users receive a visible badge that:
  • Displays on leaderboards (when premium features are enabled)
  • Shows on your profile
  • Indicates your support for Monkeytype
Badge Visibility: The premium badge appears in:
  • Daily leaderboards
  • Weekly XP leaderboards
  • Public profiles
  • Friends lists
From backend/src/api/controllers/result.ts:512-513:
const isPremium =
  (await UserDAL.checkIfUserIsPremium(user.uid, user)) || undefined;
If premium features are disabled server-wide, the isPremium flag is removed from leaderboard entries to maintain privacy.

Premium Subscription Types

Premium subscriptions can be either time-limited or lifetime.

Time-Limited Premium

Subscriptions with an expiration date:
{
  "premium": {
    "expirationTimestamp": 1735689600000 // Unix timestamp in milliseconds
  }
}
The system checks if the current time is before the expiration:
// From backend/src/dal/user.ts:1196-1213
export async function checkIfUserIsPremium(
  uid: string,
  userInfoOverride?: Pick<DBUser, "premium">,
): Promise<boolean> {
  const expirationDate = user.premium?.expirationTimestamp;

  if (expirationDate === undefined) return false;
  if (expirationDate === -1) return true; // Lifetime
  return expirationDate > Date.now();
}

Lifetime Premium

Permanent premium status indicated by:
{
  "premium": {
    "expirationTimestamp": -1  // Special value for lifetime
  }
}
Lifetime premium never expires and provides all premium benefits indefinitely.

Checking Premium Status

You can verify your premium status through the user data endpoint:
GET /users

// Response includes:
{
  "isPremium": true,
  // ... other user data
}

Premium and Leaderboards

Premium status affects leaderboard display:

Weekly XP Leaderboard

From backend/src/services/weekly-xp-leaderboard.ts:204-206:
if (!premiumFeaturesEnabled) {
  resultsWithRanks = resultsWithRanks.map((it) => omit(it, ["isPremium"]));
}
Premium badges are only shown when:
  1. Premium features are enabled server-wide
  2. The endpoint explicitly includes premium data

Daily Leaderboards

Similar logic applies to daily leaderboards. Premium status is included in the entry but may be filtered based on server configuration.

Result Retrieval Limits

When fetching results, the limit depends on your premium status: API Endpoint:
GET /users/results?limit=500&offset=0

// Premium: Can retrieve up to 10,000 results
// Regular: Can retrieve up to 1,000 results
From backend/src/api/controllers/result.ts:97-117:
let limit =
  req.query.limit ??
  Math.min(req.ctx.configuration.results.maxBatchSize, maxLimit);

if (limit + offset > maxLimit) {
  if (offset < maxLimit) {
    // Batch is partly in the allowed range
    limit = maxLimit - offset;
  } else {
    throw new MonkeyError(422, `Max results limit of ${maxLimit} exceeded.`);
  }
}
Even with premium, you cannot retrieve results beyond your limit in a single request. The maxBatchSize (typically 1000) controls how many results can be fetched at once. Use pagination with offset to retrieve all results.

Premium Feature Checks

The system performs two checks for premium features:
  1. Server-wide check: Are premium features enabled?
  2. User check: Does this user have an active premium subscription?
// Example from backend/src/api/controllers/result.ts:88-90
const premiumFeaturesEnabled = req.ctx.configuration.users.premium.enabled;
const userHasPremium = await UserDAL.checkIfUserIsPremium(uid);
Both must be true for premium features to work.

Data Logging

Premium status is logged when results are requested:
// From backend/src/api/controllers/result.ts:124-133
void addLog(
  "user_results_requested",
  {
    limit,
    offset,
    onOrAfterTimestamp,
    isPremium: userHasPremium,
  },
  uid,
);
This helps track premium feature usage and optimize server resources.

Technical Details

Database Schema

Premium information is stored in the user document:
interface DBUser {
  premium?: {
    expirationTimestamp: number; // -1 for lifetime, or Unix timestamp
  };
  // ... other fields
}

Premium Check Aggregation

For MongoDB aggregation pipelines (used in friends leaderboards), premium status is calculated inline:
// From backend/src/dal/user.ts:1337-1350
isPremium: {
  $cond: {
    if: {
      $or: [
        { $eq: ["$premium.expirationTimestamp", -1] },
        {
          $gt: ["$premium.expirationTimestamp", { $toLong: "$$NOW" }],
        },
      ],
    },
    then: true,
    else: "$$REMOVE",
  },
}

Frequently Asked Questions

  • You’ll revert to the 1,000 result limit
  • You’ll lose access to full test activity history
  • Your premium badge will be removed
  • Your existing results beyond 1,000 are not deleted, but cannot be retrieved via the API
Yes! You can view your current test activity (last 372 days) via:
GET /users/currentTestActivity
Premium unlocks full historical data by year.
Use the results endpoint with pagination to export all your data:
// Fetch in batches of 1000
GET /users/results?limit=1000&offset=0
GET /users/results?limit=1000&offset=1000
// ... continue until all results retrieved
Premium features may be disabled server-wide. Contact your instance administrator to enable them.

Build docs developers (and LLMs) love