TheArchitect

Real-Time Game Leaderboard

AWS architecture template · Sub-millisecond leaderboard reads via ElastiCache Redis sorted sets backed by DynamoDB for durable score storage.

Real-Time Game Leaderboard is a free AWS architecture template built with Lambda, API Gateway, CloudWatch, DynamoDB, ElastiCache and IAM. Open it in TheArchitect to edit the diagram, estimate monthly cost, and export the CloudFormation or Terraform that deploys it.

Game APIScore SubmitterLeaderboard Re…Leaderboard Re…Player ScoresGame Lambda Ro…Cache CPU Alarm
Real-Time Game Leaderboard architecture diagram

AWS services in this template

  • Lambda×2
  • API Gateway
  • CloudWatch
  • DynamoDB
  • ElastiCache
  • IAM

Deployment notes

Needs input

  • Set ElastiCache subnet group and security group IDs.
  • Add DynamoDB partition and sort key names to match game schema.

Generated CloudFormation — 7 resources

Logical IDResource type
GameAPIapigatewayAWS::ApiGateway::RestApi
ScoreSubmitterlambdaAWS::Lambda::Function
LeaderboardReaderlambdaAWS::Lambda::Function
LeaderboardRediselasticacheAWS::ElastiCache::CacheCluster
PlayerScoresdynamodbAWS::DynamoDB::Table
GameLambdaRoleiamAWS::IAM::Role
CacheCPUAlarmcloudwatchAWS::CloudWatch::Alarm
View the full CloudFormation template
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Generated by TheArchitect — https://www.thecloudarchitect.dev",
  "Metadata": {
    "TheArchitect": {
      "Edges": [
        {
          "From": "ScoreSubmitterlambda",
          "To": "LeaderboardRediselasticache",
          "Label": "ZADD score"
        },
        {
          "From": "ScoreSubmitterlambda",
          "To": "PlayerScoresdynamodb",
          "Label": "durable write"
        },
        {
          "From": "LeaderboardReaderlambda",
          "To": "LeaderboardRediselasticache",
          "Label": "ZREVRANGE top-N"
        },
        {
          "From": "GameLambdaRoleiam",
          "To": "ScoreSubmitterlambda",
          "Label": "execution role"
        },
        {
          "From": "GameLambdaRoleiam",
          "To": "LeaderboardReaderlambda",
          "Label": "execution role"
        }
      ]
    }
  },
  "Resources": {
    "GameAPIapigateway": {
      "Type": "AWS::ApiGateway::RestApi",
      "Properties": {
        "Name": "game-leaderboard-api",
        "Description": "Game Leaderboard REST API",
        "EndpointConfiguration": {
          "Types": [
            "REGIONAL"
          ]
        }
      }
    },
    "ScoreSubmitterlambda": {
      "Type": "AWS::Lambda::Function",
      "DependsOn": [
        "GameLambdaRoleiam"
      ],
      "Properties": {
        "FunctionName": "game-score-submitter",
        "Runtime": "python3.12",
        "Handler": "submit.handler",
        "MemorySize": 256,
        "Timeout": 10,
        "Description": "Validates and writes player score to both Redis (ZADD) and DynamoDB for durability.",
        "Role": {
          "Fn::GetAtt": [
            "GameLambdaRoleiam",
            "Arn"
          ]
        }
      }
    },
    "LeaderboardReaderlambda": {
      "Type": "AWS::Lambda::Function",
      "DependsOn": [
        "GameLambdaRoleiam"
      ],
      "Properties": {
        "FunctionName": "game-leaderboard-reader",
        "Runtime": "python3.12",
        "Handler": "leaderboard.handler",
        "MemorySize": 256,
        "Timeout": 5,
        "Description": "Returns top-N scores via Redis ZREVRANGE — sub-millisecond reads served from cache.",
        "Role": {
          "Fn::GetAtt": [
            "GameLambdaRoleiam",
            "Arn"
          ]
        }
      }
    },
    "LeaderboardRediselasticache": {
      "Type": "AWS::ElastiCache::CacheCluster",
      "Properties": {
        "ClusterName": "game-leaderboard-redis",
        "Engine": "redis",
        "EngineVersion": "7.1",
        "CacheNodeType": "cache.t3.small",
        "NumCacheNodes": 1,
        "AtRestEncryptionEnabled": true,
        "TransitEncryptionEnabled": true,
        "SnapshotRetentionLimit": 1
      }
    },
    "PlayerScoresdynamodb": {
      "Type": "AWS::DynamoDB::Table",
      "Properties": {
        "TableName": "player-scores",
        "BillingMode": "PAY_PER_REQUEST",
        "AttributeDefinitions": [
          {
            "AttributeName": "id",
            "AttributeType": "S"
          }
        ],
        "KeySchema": [
          {
            "AttributeName": "id",
            "KeyType": "HASH"
          }
        ],
        "PointInTimeRecoverySpecification": {
          "PointInTimeRecoveryEnabled": true
        }
      }
    },
    "GameLambdaRoleiam": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "RoleName": "game-lambda-role",
        "Description": "Execution role for score submitter and leaderboard reader Lambdas",
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        },
        "ManagedPolicyArns": [
          "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
        ]
      }
    },
    "CacheCPUAlarmcloudwatch": {
      "Type": "AWS::CloudWatch::Alarm",
      "Properties": {
        "AlarmName": "game-cache-cpu-high",
        "AlarmDescription": "ElastiCache CPU above 80% — consider upgrading node type or adding read replicas",
        "Namespace": "AWS/ElastiCache",
        "MetricName": "EngineCPUUtilization",
        "Statistic": "Average",
        "Period": 60,
        "EvaluationPeriods": 3,
        "Threshold": 80,
        "ComparisonOperator": "GreaterThanThreshold",
        "TreatMissingData": "notBreaching"
      }
    }
  }
}

Generated by TheArchitect from the diagram above. Review values such as names, CIDR ranges and instance sizes before deploying to your account.

Related templates