Amazon GameLift Streams quietly became one of AWS’s most useful game-industry tools in 2026, yet most developers still confuse it with Amazon GameLift Servers, the older dedicated-server product. They solve different problems. GameLift Servers spins up dedicated compute for session-based multiplayer games. GameLift Streams does something else entirely: it takes an existing game build, whether a AAA title or a small indie project, and streams it at up to 1080p and 60 frames per second straight to a browser tab, with no client install and no local GPU required. As of September 2026, AWS runs the service across 12 regions worldwide and prices it by the second of streaming capacity actually consumed.
This tutorial walks through the full setup, from packaging your build for S3 to launching your first browser-based test stream, choosing the right stream class for your budget, and wiring the Web SDK into a front end. We will also cover the pitfalls that trip up first-time users, a troubleshooting list pulled from AWS’s own developer guide, and a full working project you can adapt today.
Don't miss new tech stories on Google
Add Tech Insider once in the Google app and our stories appear in your news suggestions.
What Amazon GameLift Streams Actually Does
Amazon GameLift Streams is a managed cloud content-streaming service. Instead of asking players to download and install a game, a publisher uploads the built executable and assets once, and AWS runs the game on managed GPU capacity in the cloud, encodes the video and audio output, and streams it to any device that has a modern browser: a laptop, a phone, a tablet, or a smart TV. Player input travels back over the same connection. AWS describes the target experience as “up to 1080p resolution and 60 frames-per-second,” delivered over its own network backbone rather than the public internet where possible, according to the official GameLift Streams product page.
The billing model is the part most engineers get wrong on their first read. GameLift Streams does not bill per player license, per download, or per concurrent user in the way a typical SaaS product might. It bills for stream capacity per second, whether that capacity is actively streaming a session or sitting idle and ready to accept one, per the GameLift Streams pricing documentation. That distinction matters enormously for cost planning, and we will return to it in the pricing section below.
If you already run dedicated multiplayer servers on Amazon GameLift Servers, think of GameLift Streams as the distribution layer that sits in front of, or completely independent from, that backend. A racing game might use GameLift Servers for physics and matchmaking while using GameLift Streams purely to let players demo the game in a browser before they commit to a full download. The two products even share a family name because AWS positions them as complementary halves of a game-hosting stack, not competing options.
GameLift Streams vs GameLift Servers: Choosing the Right Product
Because both products share the GameLift name, teams researching AWS’s game-hosting options often assume they are two tiers of the same service. They are not. Amazon GameLift Servers, covered in detail in AWS’s GameLift Servers features documentation, deploys dedicated compute instances that run your actual multiplayer game server binary. It handles fleet management, FlexMatch matchmaking for up to 200 players per session, and scale-to-zero autoscaling introduced in early 2026. Players still need the client game installed locally; GameLift Servers only hosts the authoritative simulation and network layer.
GameLift Streams solves a completely different problem: distribution and accessibility. It does not run your multiplayer logic at all unless your game build happens to be a full multiplayer client. Instead, it takes whatever executable you give it, whether that is a single-player demo, a full retail build, or a marketing showcase, and streams the rendered output to a browser. A studio building a competitive shooter would typically use GameLift Servers for the match backend and, separately, GameLift Streams to let potential players try a demo version instantly from a marketing landing page with zero download friction.
The decision point is simple: if your bottleneck is running authoritative multiplayer sessions, look at GameLift Servers, covered in our AWS game server hosting setup guide. If your bottleneck is getting a playable build in front of someone without an install step, GameLift Streams is the right tool, and it is the one this tutorial focuses on.
Real-World Use Cases for Game Streaming
The most common production use case for GameLift Streams is the frictionless demo: a publisher embeds a playable build directly into a store page, a press kit, or a social media landing page, and a visitor starts playing within seconds instead of waiting on a multi-gigabyte download. Because the stream runs inside a normal browser tab, there is no platform gatekeeping and no install prompt standing between curiosity and a first impression.
A second use case is porting older or platform-locked titles to reach devices that could never run them natively. A PC-only game can suddenly become playable on a low-powered Chromebook, a budget Android tablet, or a smart TV, since the actual rendering happens on AWS’s GPU capacity rather than on the end device. This is functionally similar to what consumer services like GeForce NOW offer players for their own game libraries, except GameLift Streams puts that capability directly into a publisher’s own product rather than a third-party client.
A third, less obvious use case is internal QA and localization review. Instead of shipping a new build to every tester’s machine, a studio can point QA staff at a stream group running the latest build, catching platform-specific rendering bugs from a single centralized deployment rather than chasing down driver differences across a fleet of test machines.
Security and Access Control Considerations
Because GameLift Streams runs your game binary on AWS-managed infrastructure, the security surface splits into two parts: protecting the AWS control plane, and protecting the stream session itself. On the control plane side, the IAM policy from Step 1 should never be broader than the gameliftstreams namespace plus the specific S3 bucket you use for builds. Avoid attaching this policy to a role that also has EC2 or IAM management permissions, since a compromised build pipeline credential should not be able to touch unrelated infrastructure.
On the session side, always start stream sessions from your own backend rather than exposing raw AWS credentials to the browser, exactly as shown in the Node.js proxy example later in this tutorial. The browser client only ever needs the SDP offer and answer for the WebRTC connection; it should never see an AWS access key or secret. This is a standard proxy pattern in any AWS-backed real-time service, and skipping it is one of the fastest ways to leak account access to anyone who opens the browser developer console.
Regional choice also doubles as a data-residency control. Because AWS lets you pin a stream group to a specific region, teams operating under data-localization requirements in the European Union or elsewhere can keep both the game build and every streamed session confined to an in-region stream group, using the region table later in this article to pick a compliant location.
Prerequisites and Required Versions
Before starting, gather the following. None of this is optional; skipping any item below is the single biggest source of failed application creation according to AWS’s own developer guide.
- An AWS account with billing enabled and an IAM user or role that has permissions for GameLift Streams, Amazon S3, and CloudWatch Logs.
- AWS CLI v2 (the current major release line as of 2026) installed and configured with
aws configure. - A Windows-based game build (Windows Server 2022 is the currently supported runtime environment for GameLift Streams application definitions), packaged as an uncompressed folder rather than a ZIP file or installer.
- An S3 bucket in the same AWS region where you plan to run your stream group.
- Node.js 18 or later if you plan to embed the GameLift Streams Web SDK (currently at v1.3.0) into a custom web front end.
- A modern browser that supports WebRTC for testing (Chrome, Edge, or Firefox all work; AWS’s test player runs directly inside the GameLift Streams console).
- Roughly 60 to 90 minutes for the full walkthrough, plus additional time for large game builds to upload and validate.
One requirement catches almost everyone off guard: GameLift Streams expects an uncompressed folder structure in S3, not a compressed archive. If your build pipeline normally outputs a ZIP for distribution, add a step that unzips it into a plain folder before the S3 upload.
Step 1: Set Up IAM Permissions
Create a dedicated IAM policy for GameLift Streams rather than reusing an overly broad admin role. At minimum, the role needs permissions for the gameliftstreams:* action namespace, plus s3:GetObject and s3:ListBucket on your build bucket, and logs:CreateLogGroup / logs:PutLogEvents if you want CloudWatch monitoring on stream sessions.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GameLiftStreamsFullAccess",
"Effect": "Allow",
"Action": "gameliftstreams:*",
"Resource": "*"
},
{
"Sid": "GameLiftStreamsS3Access",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::your-gamelift-build-bucket",
"arn:aws:s3:::your-gamelift-build-bucket/*"
]
},
{
"Sid": "GameLiftStreamsLogging",
"Effect": "Allow",
"Action": ["logs:CreateLogGroup", "logs:PutLogEvents"],
"Resource": "arn:aws:logs:*:*:log-group:/aws/gameliftstreams/*"
}
]
}
Attach this policy to the IAM user or role you will use for the rest of the tutorial, and confirm the AWS CLI picks it up with aws sts get-caller-identity.
Step 2: Package Your Game Build Correctly
Place your compiled Windows executable and every asset it depends on inside a single root folder. Do not compress it. AWS’s developer guide is explicit that GameLift Streams copies files from this uncompressed folder into its own internal managed storage during application creation, and it validates the folder structure at that point. A ZIP file or an installer executable will fail validation because there is nothing for the service to mount and launch directly.
Note the relative path to your main executable from the root of that folder, for example Game\Bin\Win64\Game.exe. You will need this exact string in Step 4.
Step 3: Upload the Build to S3
Create an S3 bucket in the region you intend to stream from, then sync the entire uncompressed build folder to it.
aws s3 mb s3://your-gamelift-build-bucket --region us-west-2
aws s3 sync ./build/Win64Release s3://your-gamelift-build-bucket/mygame/ \
--region us-west-2
Verify the upload completed and the folder structure is intact.
aws s3 ls s3://your-gamelift-build-bucket/mygame/ --recursive | head -20
Step 4: Create a GameLift Streams Application
An application in GameLift Streams is the definition that points at your S3 build location and your launch executable. Create it through the console under Amazon GameLift Streams > Applications > Create application, or through the CLI, which mirrors the underlying API operations (CreateApplication, CreateStreamGroup, StartStreamSession).
aws gameliftstreams create-application \
--description "MyGame browser demo build" \
--executable-path "Game\Bin\Win64\Game.exe" \
--runtime-environment Type=WINDOWS,Version=2022 \
--application-source-uri s3://your-gamelift-build-bucket/mygame/ \
--region us-west-2
The response returns an application ARN. Save it; you will need it to associate a stream group in Step 7.
Step 5: Wait for the Application to Reach READY Status
GameLift Streams copies your build into internal managed storage and validates it. This can take anywhere from a few minutes for a small indie build to well over an hour for a large AAA title with dozens of gigabytes of assets. Poll the application status before attempting to stream from it.
aws gameliftstreams get-application \
--identifier arn:aws:gameliftstreams:us-west-2:123456789012:application/a-abc123 \
--query 'Status' \
--region us-west-2
Once status returns READY, the AWS FAQ notes you can safely delete the original files from your S3 bucket, since GameLift Streams has already copied everything it needs into its own storage. Leaving the original build sitting in S3 costs you standard S3 storage fees for no benefit.
Step 6: Choose a Stream Class
A stream class is a predefined bundle of compute and GPU capacity that GameLift Streams provisions per concurrent player. AWS does not publish exact vCPU or RAM counts per class publicly; instead it differentiates classes by relative performance tier (high vs ultra) and by hourly price. As of September 2026, the documented classes are gen4n_high, gen4n_ultra, gen4n_win2022, gen5n_high, gen5n_ultra, gen5n_win2022, and the newer gen6n_ultra_win2022.
| Stream Class | Tier | Price per Capacity-Hour (us-west-2) | Best For |
|---|---|---|---|
| gen4n_high | Standard | $0.4982 | 2D and lightweight 3D titles, demos |
| gen4n_ultra | Premium | $0.9288 | Graphically demanding 3D games |
| gen5n_high | Standard, newer gen | $0.7625 | Better price-performance than gen4n_ultra for mid-tier titles |
| gen5n_ultra | Premium, newer gen | $1.4544 | High-fidelity AAA builds |
| gen4n_win2022 | Windows runtime | $1.5100 | Full Windows Server 2022 environments |
| gen5n_win2022 | Windows runtime, newer gen | $2.1330 | Windows apps needing newer-gen throughput |
| gen6n_ultra_win2022 | Latest generation | $1.82 | Newest hardware generation for Windows-based streams |
Pricing varies by region. The same gen4n_high class costs $0.5205 per hour in us-east-1 (N. Virginia), $0.5419 in eu-west-1 (Ireland), and $0.6571 per stream group capacity-hour in eu-central-1 (Frankfurt). Always check the pricing page for your target region before committing capacity, since the spread between the cheapest and most expensive region for the same class can run 15 to 30 percent.
Step 7: Create a Stream Group
A stream group is where you actually provision capacity: it combines a stream class, a region, and a capacity count (the number of concurrent streaming sessions you want ready to serve).
aws gameliftstreams create-stream-group \
--description "MyGame demo stream group" \
--default-application-identifier arn:aws:gameliftstreams:us-west-2:123456789012:application/a-abc123 \
--stream-class gen4n_high \
--location-configurations "LocationName=us-west-2,AlwaysOnCapacity=1,OnDemandCapacity=4" \
--region us-west-2
The AlwaysOnCapacity value keeps a small number of instances warm and ready, avoiding cold-start delay for the first player. OnDemandCapacity defines the ceiling the stream group can burst to when demand spikes. Set AlwaysOnCapacity conservatively during testing, since it is billed continuously regardless of whether a player is connected.
Step 8: Associate the Stream Group With Your Application
If you did not set a default application when creating the stream group, link them explicitly.
aws gameliftstreams update-stream-group \
--identifier sg-xyz789 \
--add-application-identifiers arn:aws:gameliftstreams:us-west-2:123456789012:application/a-abc123 \
--region us-west-2
Attempting to start a stream session before this association exists is one of the most common failure points reported in AWS’s own troubleshooting guidance, producing a placement or availability error rather than a clear “not linked” message.
Step 9: Launch a Test Stream From the Console
Open the GameLift Streams console, navigate to your application, and choose the test stream option. This opens a browser-based player embedded directly in the console, using the associated stream group’s capacity. Use this step to confirm your build actually launches, renders correctly, and accepts keyboard or gamepad input before you write a single line of front-end integration code.
If the test stream fails to load, check the application status is READY, confirm the stream group has available capacity, and check CloudWatch Logs for the specific launch error from inside the streaming instance.
Step 10: Integrate the Web SDK Into Your Front End
For a production front end, use the GameLift Streams Web SDK (currently v1.3.0) rather than the console test player. The SDK handles the WebRTC connection, input capture, and video rendering inside a target HTML element.
import { GameLiftStreams } from '@aws/gameliftstreams-web-sdk';
async function startGame(containerEl) {
const client = new GameLiftStreams({
videoElement: document.getElementById('stream-video'),
audioElement: document.getElementById('stream-audio'),
inputConfiguration: { autoMouseCapture: true, autoKeyboardCapture: true }
});
const session = await client.startSession({
signalRequest: async (offer) => {
const res = await fetch('/api/start-stream-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ sdpOffer: offer })
});
return res.json();
}
});
session.attachInput(containerEl);
}
The /api/start-stream-session endpoint on your own backend should call the GameLift Streams StartStreamSession API with your stream group identifier and forward the resulting SDP answer back to the browser. Keep that call server-side so your AWS credentials never reach the client.
Step 11: Monitor Capacity and Costs With CloudWatch
Because billing is capacity-per-second regardless of active use, monitoring idle-versus-active capacity is the single highest-leverage thing you can do to control spend. Set up a CloudWatch dashboard tracking stream group utilization, and configure a billing alarm tied to your expected monthly ceiling.
aws cloudwatch put-metric-alarm \
--alarm-name "GameLiftStreams-MonthlySpendCeiling" \
--metric-name EstimatedCharges \
--namespace AWS/Billing \
--statistic Maximum \
--period 21600 \
--threshold 500 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 1 \
--dimensions Name=Currency,Value=USD \
--region us-east-1
Step 12: Clean Up or Scale Down When Testing Ends
Reduce AlwaysOnCapacity to zero on stream groups you are not actively using, and delete test applications you no longer need. Because capacity-hours bill continuously, an always-on test stream group left running over a weekend can quietly cost more than an entire week of active development testing.
aws gameliftstreams update-stream-group \
--identifier sg-xyz789 \
--location-configurations "LocationName=us-west-2,AlwaysOnCapacity=0,OnDemandCapacity=0" \
--region us-west-2
Regional Availability in September 2026
GameLift Streams launched in a handful of regions and expanded significantly through 2026. AWS added six new locations during the year, bringing total coverage to 12 regions, according to the supported locations documentation.
| Region | Code | Status |
|---|---|---|
| US East (N. Virginia) | us-east-1 | Original launch region |
| US East (Ohio) | us-east-2 | Original launch region |
| US West (Oregon) | us-west-2 | Original launch region |
| Europe (Ireland) | eu-west-1 | Original launch region |
| Europe (Frankfurt) | eu-central-1 | Original launch region |
| Asia Pacific (Tokyo) | ap-northeast-1 | Original launch region |
| Asia Pacific (Seoul) | ap-northeast-2 | Added 2026 |
| Asia Pacific (Mumbai) | ap-south-1 | Added 2026 |
| Asia Pacific (Sydney) | ap-southeast-2 | Added 2026 |
| Europe (Stockholm) | eu-north-1 | Added 2026 |
| Europe (London) | eu-west-2 | Added 2026 |
| South America (São Paulo) | sa-east-1 | Added 2026 |
All stream class families are available in every supported location, according to AWS’s stream-class-locations documentation, so the decision of which region to deploy in comes down to latency to your player base and the per-region price differences noted in Step 6. A useful mental model: for a fast-paced action game, treat anything beyond a few hundred kilometers of physical distance between the player and the stream group as a real latency cost, since the round trip now includes video encoding, network transit, and decoding on top of normal input lag. Turn-based or slower-paced genres tolerate a wider geographic radius far more comfortably, so a single stream group covering an entire continent may be perfectly acceptable for a puzzle game while a competitive shooter needs multiple regional stream groups to feel responsive everywhere.
If your player base spans multiple continents, the practical pattern is to create one stream group per region using the same application ARN, then route incoming session requests through your backend based on the player’s detected location. This keeps a single source of truth for your game build while letting you scale regional capacity independently, spinning up more OnDemandCapacity in regions with growing player counts without touching the others.
How the Cost Model Compares to Alternatives
GameLift Streams is not the only path to browser-based or remote game streaming, and it is worth comparing it honestly against the alternatives before committing engineering time. A self-hosted stack using Sunshine and Moonlight on AWS G7 instances gives you full control over the GPU instance but pushes all the orchestration, scaling, and session management work back onto your own team. Consumer services like GeForce NOW or Shadow’s cloud gaming service are built for end users streaming their own game libraries, not for publishers who need to embed a streaming demo into their own website or app.
| Approach | Billing Model | Who Manages Infrastructure | Best Fit |
|---|---|---|---|
| Amazon GameLift Streams | Per-second stream capacity | AWS (fully managed) | Publishers embedding streaming demos or full games into a website or app |
| Self-hosted Sunshine/Moonlight on EC2 | Standard EC2 GPU instance hourly rate | Your own team | Teams needing full OS-level control |
| AWS game server hosting (GameLift Servers) | Dedicated instance hours | AWS provisions, you configure | Session-based dedicated multiplayer, not content streaming |
| GeForce NOW / Shadow | Consumer subscription | Provider | End users streaming their existing game libraries, not publisher demos |
The distinction that matters most for a publisher weighing these options is control over the embed. GameLift Streams is designed to be dropped into a web page or app you own, with your own branding around the stream, whereas GeForce NOW and Shadow are standalone consumer clients that a player launches independently of any single publisher’s site.
Run the numbers on a realistic scenario to see how the cost model plays out in practice. A marketing campaign running a browser demo on gen4n_high capacity in us-west-2, with two AlwaysOnCapacity units to guarantee instant load for the first visitors and a burst ceiling of ten OnDemandCapacity units during a launch-day traffic spike, would cost roughly $1 per hour for the always-on baseline (2 units at $0.4982) plus whatever fraction of the 10-unit burst ceiling actually gets used during peak minutes. Compare that to provisioning ten dedicated g5 or g6 EC2 GPU instances yourself around the clock for the same campaign, and the per-second billing model on GameLift Streams usually wins decisively for spiky, promotional traffic patterns, while a steady, predictable, always-busy workload can sometimes favor a self-managed EC2 fleet instead.
Five Common Pitfalls When Setting Up GameLift Streams
- Uploading a compressed build. GameLift Streams requires an uncompressed folder in S3. A ZIP or installer will fail application validation with a vague error rather than a clear “wrong format” message.
- Leaving AlwaysOnCapacity high during development. Every unit of always-on capacity bills continuously, whether or not a developer is actively testing. Teams routinely leave this at a testing-era value and get an unpleasant monthly bill.
- Mismatching the executable path. The launch path is relative to the S3 root folder, not an absolute Windows path. A single wrong backslash or an extra parent folder prevents the application from reaching READY status.
- Skipping the stream group association step. Creating an application and a stream group separately, then forgetting to link them, produces a placement error when you try to start your first stream session that has nothing to do with your game code.
- Forgetting regional pricing differences. The same stream class can cost 15 to 30 percent more in one region than another. Teams that pick a region purely for player latency without checking the price table sometimes discover the gap only after the first invoice.
Troubleshooting Guide
These are the issues most frequently reported against GameLift Streams setups, along with the fix AWS’s stream management documentation and the AWS GameTech blog’s first-deployment walkthrough point to.
- Application stuck in PROCESSING status for a long time. Large builds with tens of gigabytes of assets can take well over an hour to validate. Check the build size before assuming something is broken.
- Application creation fails immediately. Almost always caused by an uncompressed-vs-compressed mismatch, or an S3 bucket in a different region than expected. Confirm both before retrying.
- Test stream returns a placement error. The stream group has no available capacity, or it is not associated with the application. Check both the association and the current AlwaysOnCapacity / OnDemandCapacity values.
- Stream loads but the game window is black. Usually an in-game fullscreen or resolution setting conflicting with the streaming session’s virtual display. Force windowed mode or a supported resolution in your build’s launch configuration.
- High input latency during testing. Confirm you are testing from a region geographically close to your chosen stream group region; testing cross-continent will always show inflated latency that will not reflect real player experience.
- IAM permission denied errors on CLI calls. The
gameliftstreams:*action namespace is separate from GameLift Servers permissions; a role scoped only for the older Servers product will not work here. - Web SDK fails to connect from a custom front end. Confirm your backend’s
StartStreamSessioncall correctly forwards the SDP offer and returns the SDP answer; a mismatched signaling payload is the most common integration bug. - Unexpectedly high monthly bill. Audit every stream group for stale AlwaysOnCapacity values left over from testing, and confirm you deleted the original S3 build files after the application reached READY status, since duplicated storage does add up over time on large titles.
Advanced Tips for Production Deployments
Once your basic setup works, a few adjustments separate a demo from a production-grade deployment. First, split stream groups by region and route players to the nearest one using Route 53 latency-based routing or your own geo-IP logic, rather than running a single global stream group and accepting the latency penalty for distant players. A player in São Paulo routed to a us-east-1 stream group will feel every millisecond of that round trip through added input lag, so treat regional stream group placement as a latency decision first and a cost decision second.
Second, treat AlwaysOnCapacity as a knob you tune against real traffic data rather than a set-and-forget value. Start near zero, watch CloudWatch utilization during a soft launch, and raise it only enough to cover your typical cold-start tolerance for the first players of the day. Many teams find that a small always-on buffer during known peak windows, combined with zero always-on capacity overnight, captures most of the latency benefit at a fraction of the always-on cost.
Third, use the newer generation stream classes (gen5 and gen6) selectively rather than by default. The pricing table above shows a real cost gap between gen4 and gen5/gen6 classes; reserve the newer, pricier tiers for titles that genuinely need the extra headroom, and keep lighter 2D or stylized titles on gen4n_high. Running a quick side-by-side test stream on two classes before committing a production stream group to one is worth the extra 20 minutes it takes.
Fourth, treat your Web SDK integration as a first-class piece of front-end code, not an afterthought bolted onto a marketing page. Handle reconnect logic explicitly: a dropped WebRTC connection due to a flaky mobile network should attempt to resume the same stream session rather than forcing the player to restart the entire game from a cold boot.
Finally, build a kill switch into your deployment pipeline that can immediately zero out AlwaysOnCapacity across every stream group if a billing alarm fires. A five-minute delay in reacting to a runaway cost alert on a global-scale deployment can represent a meaningful chunk of a monthly budget, especially on gen5n_win2022 or gen6n_ultra_win2022 capacity, which bill at more than double the rate of gen4n_high.
Complete Working Project: A Minimal Browser Demo
Putting the steps above together, here is the minimal end-to-end project structure for a working GameLift Streams browser demo.
project/
├── build/ # Uncompressed Windows game build
│ └── Win64Release/
│ └── Game/Bin/Win64/Game.exe
├── infra/
│ ├── iam-policy.json # Policy from Step 1
│ └── deploy.sh # Wraps the CLI calls from Steps 3-8
├── server/
│ └── index.js # Node backend proxying StartStreamSession
└── web/
├── index.html # Contains #stream-video and #stream-audio
└── main.js # Web SDK integration from Step 10
The deploy.sh script chains the CLI commands from this tutorial in order: create the S3 bucket, sync the build, create the application, poll until READY, create the stream group, and associate the two.
#!/bin/bash
set -e
BUCKET="your-gamelift-build-bucket"
REGION="us-west-2"
aws s3 mb s3://$BUCKET --region $REGION || true
aws s3 sync ./build/Win64Release s3://$BUCKET/mygame/ --region $REGION
APP_ARN=$(aws gameliftstreams create-application \
--description "MyGame browser demo build" \
--executable-path "Game\\Bin\\Win64\\Game.exe" \
--runtime-environment Type=WINDOWS,Version=2022 \
--application-source-uri s3://$BUCKET/mygame/ \
--region $REGION --query 'Arn' --output text)
echo "Waiting for application to reach READY..."
until [ "$(aws gameliftstreams get-application --identifier $APP_ARN --query 'Status' --output text --region $REGION)" == "READY" ]; do
sleep 30
done
SG_ID=$(aws gameliftstreams create-stream-group \
--description "MyGame demo stream group" \
--default-application-identifier $APP_ARN \
--stream-class gen4n_high \
--location-configurations "LocationName=$REGION,AlwaysOnCapacity=1,OnDemandCapacity=4" \
--region $REGION --query 'Id' --output text)
echo "Stream group $SG_ID is live for application $APP_ARN"
The Node backend accepts a session start request from the front end, calls StartStreamSession against your stream group, and forwards the SDP answer, keeping the AWS credentials server-side the entire time.
const { GameLiftStreamsClient, StartStreamSessionCommand } = require('@aws-sdk/client-gameliftstreams');
const express = require('express');
const app = express();
app.use(express.json());
const client = new GameLiftStreamsClient({ region: 'us-west-2' });
app.post('/api/start-stream-session', async (req, res) => {
const command = new StartStreamSessionCommand({
StreamGroupIdentifier: process.env.STREAM_GROUP_ID,
ApplicationIdentifier: process.env.APPLICATION_ARN,
SignalRequest: req.body.sdpOffer
});
const response = await client.send(command);
res.json({ sdpAnswer: response.SignalResponse });
});
app.listen(3000, () => console.log('GameLift Streams proxy listening on :3000'));
This gives you a complete, deployable path from a raw Windows build to a working browser stream, wired through the same steps this tutorial covered individually. For teams already comfortable with the broader cloud computing tooling ecosystem, extending this into a CI/CD pipeline that rebuilds and redeploys the application on every release is a natural next step.
Frequently Asked Questions
Is Amazon GameLift Streams the same as Amazon GameLift Servers?
No. GameLift Servers hosts dedicated, session-based multiplayer game servers. GameLift Streams is a content-streaming service that runs an existing game build in the cloud and streams the video and audio to a browser. They can be used together but solve different problems.
How much does Amazon GameLift Streams cost?
Pricing is per stream capacity-hour by stream class and region. In us-west-2 (Oregon), gen4n_high costs $0.4982 per hour and gen5n_ultra costs $1.4544 per hour, as of the GameLift Streams pricing page. Billing applies whether or not capacity is actively streaming a player, so idle always-on capacity still bills.
What resolution and frame rate does GameLift Streams support?
AWS documentation states GameLift Streams delivers up to 1080p resolution at 60 frames per second to end-player devices with a browser.
Which regions is GameLift Streams available in as of September 2026?
Twelve regions: US East (N. Virginia and Ohio), US West (Oregon), Europe (Ireland, Frankfurt, Stockholm, London), Asia Pacific (Tokyo, Seoul, Mumbai, Sydney), and South America (São Paulo). Six of these were added during 2026, expanding from the original six-region launch footprint.
Does GameLift Streams support Unity and Unreal games?
GameLift Streams is engine-agnostic since it streams the compiled Windows executable output, not the engine source. AWS’s published SDK options focus on the Web SDK and backend API clients (JavaScript, Python via Boto3) rather than engine-specific plugins, so any Windows-built game from Unity, Unreal, or a custom engine can be uploaded as long as it runs as a standard Windows Server 2022 executable.
Do I need to compress my game build before uploading it?
No, and doing so will break application creation. GameLift Streams requires an uncompressed folder structure in S3 so it can copy and mount the files directly.
Can I delete my S3 build files after setup?
Yes. Once your application status reaches READY, AWS’s own FAQ states GameLift Streams has already copied the files into its internal managed storage, so the original S3 copy can be deleted to avoid ongoing storage charges.
What is the difference between AlwaysOnCapacity and OnDemandCapacity?
AlwaysOnCapacity keeps a set number of streaming instances warm and billed continuously so the first players of a session have no cold-start delay. OnDemandCapacity defines the maximum the stream group can burst up to when player demand exceeds the always-on baseline, and only bills for the time it is actually provisioned.


