Part 23 of Learn AWS from Scratch

Analyzing Data: Athena, Redshift and Glue

Getting answers from your data. Querying S3 with SQL in Athena, a data warehouse with Redshift, preparing data with Glue, plus search, big jobs, dashboards and streams, with a hands-on where Parquet cuts what a query reads.

In this article
  1. Two kinds of work
  2. Amazon Athena: SQL on S3
  3. Amazon Redshift: the warehouse
  4. AWS Glue: preparing the data
  5. Lake Formation: permissions for the lake
  6. Search, big jobs and dashboards
  7. Streams: Flink and Kafka
  8. How does the data arrive?
  9. The complete picture
  10. Hands-on: Parquet cuts what a query reads
  11. Summary
  12. Test yourself

The application we finished designing in part twenty-two produces a lot of data: orders, logs and events. Then someone asks: "Which city grew the most this year?"

You could run that on your production database and slow it down for your customers. Instead, AWS has a set of services built for analysis, and this part is a guide to them.

You want Use
SQL on files in S3, with no servers Athena
A data warehouse for heavy, frequent reports Redshift
A catalog of your data, and cleaning and converting it Glue
Permissions over a whole data lake Lake Formation
Text search and log analysis OpenSearch
Big Spark or Hadoop jobs EMR
Dashboards for your team Quick Sight
Analyzing a stream as it arrives Managed Flink
Managed Apache Kafka MSK

Two kinds of work

The questions an application asks are different from the questions a business asks:

Running the application (OLTP) Analysis (OLAP)
Example Fetch order 1001 Total sales per city over three years
Rows touched A few Millions
Who asks Millions of customers A few analysts
Services RDS and DynamoDB Athena and Redshift

The secret of analytics services is storing data by column. To add up one column, there's no need to read the rest:

By row: reads everything id city amount By column: reads one column id city amount The query: SUM(amount)
To add up the amount column, row storage goes through every field, while column storage reads that column alone.

Amazon Athena: SQL on S3

Athena lets you query files in S3 directly with SQL. There's nothing to run: you describe the files as a table, and the data stays where it is.

You pay about $5 per TB of data scanned, with a 10 MB minimum per query. Creating tables and failed queries cost nothing. It suits occasional questions and analyzing logs, such as those from a load balancer or S3, and it's also where AWS points you now that S3 Select is closed to new customers.

Read less, pay less

Since the price depends on what's read, reading less means both a lower bill and a faster answer:

  • Columnar formats: convert files to Parquet or ORC, so a query reads only its columns.
  • Partitions: split the data into paths such as year=2025/, so a query skips the rest.
  • Compression: the smaller the data, the less gets scanned.
  • Larger files: thousands of tiny files slow things down, so merge them.
Athena WHERE year = 2025 year=2024/ Skipped year=2025/ Read year=2026/ Skipped
With the data split by year, a query about 2025 reads one folder and skips the others, so you pay only for what it read.

Federated queries

Your data isn't all in S3? Federated Query lets Athena reach other sources, such as DynamoDB or RDS, through a connector that runs as a Lambda function in your account. One query can even join them with your files.

Amazon Redshift: the warehouse

When reports become heavy and frequent, with many joins and many users, you need a data warehouse. Redshift is based on PostgreSQL, stores data by column, and splits a query across many nodes in parallel.

Serverless Provisioned
You choose Nothing; capacity adjusts itself The type and number of nodes
You pay for Compute time when queries run Each node per hour
Suits Changing or intermittent load Steady load, or needing Multi-AZ

Getting data in

Method When
COPY from S3 The usual way: loads in bulk and in parallel
Data Firehose A stream that lands in S3, then gets loaded with COPY
Zero-ETL Automatically replicating from sources like Aurora, RDS and DynamoDB, with no pipeline to build
INSERT row by row Avoid it for large amounts; it's very slow

Things worth knowing

  • Redshift Spectrum: query files in S3 from Redshift without loading them, and join them with your tables.
  • Snapshots: automatic and incremental, and you can copy them to another Region to recover from a disaster.
  • Multi-AZ: available on provisioned RA3 clusters, with nodes in two Availability Zones behind one endpoint.

Athena or Redshift?

Athena Redshift
The data is in S3 The warehouse, plus S3 with Spectrum
Setup None Little, with Serverless
You pay for Data scanned Compute time
Suits Occasional questions and logs Heavy, repeated reports and dashboards

Start with Athena, and move to Redshift when your queries become frequent enough for it to pay off.

AWS Glue: preparing the data

Analysis assumes the data is clean and organized, which is rarely the case. Glue is a serverless set of tools for that:

Part What it does
Data Catalog A central list of your tables and their columns, used by Athena, Redshift Spectrum and EMR
Crawlers Scan S3 and work out the columns, then add them to the catalog
ETL jobs Spark code that extracts, transforms and loads data, such as CSV to Parquet
Job bookmarks Remember what's been processed, so a job doesn't repeat old files
DataBrew Cleans data visually, with no code

A common pattern: a file lands in S3, an event starts a Glue job, and it converts the file to Parquet in another folder. Note that Glue Ray jobs closed to new customers on April 30, 2026, while Spark jobs carry on as usual.

You may also read about AWS Data Pipeline, an older service for moving and processing data on a schedule. It's closed to new customers and in maintenance mode, so use Glue or Step Functions for new work.

Lake Formation: permissions for the lake

S3 with Parquet files and a catalog is what's called a data lake. As it grows, managing access through bucket policies gets hard, because S3 knows about files, not columns.

Lake Formation gives you one place to grant access by database, table, column and even row: the sales team sees orders without card numbers, for example. These permissions apply through services like Athena, Redshift and EMR.

Search, big jobs and dashboards

OpenSearch

A database is good at finding by key. OpenSearch is good at finding by any word in any field, and at analyzing logs. It comes as managed clusters where you control the sizes, or as Serverless for changing load.

It's usually a copy of your data, not the source. Two common patterns:

  • Search over a table: DynamoDB Streams, then Lambda, then OpenSearch. You search there, then fetch the full item from the table.
  • Log analysis: CloudWatch Logs, then Firehose, then OpenSearch.

Amazon EMR

Do you have existing Spark or Hadoop jobs? EMR runs them, and you can choose to run it on EC2, on EKS or as Serverless. On EC2 there are three kinds of nodes:

Node Role Purchase option
Primary Coordinates the cluster On-Demand or Reserved
Core Runs tasks and stores data On-Demand or Reserved
Task Runs tasks only, and is optional Spot is ideal

Quick Sight

Amazon Quick Sight builds dashboards from Athena, Redshift, RDS, S3 and others. Its name was QuickSight, and since October 2025 it has been part of a broader suite called Amazon Quick, though the API still uses the old name.

  • SPICE: an in-memory engine that makes dashboards fast, without burdening the source on every view.
  • An analysis or a dashboard: you edit in an analysis, and publish it as a read-only dashboard.
  • Row-level security: each manager sees only their own region's data.

Kinesis and Firehose deliver the data. What if you want to analyze it as it arrives, such as spotting a suspicious pattern within seconds?

Managed Service for Apache Flink (formerly Kinesis Data Analytics) runs Flink applications that read from a Kinesis stream or from MSK, without you managing the cluster.

Amazon MSK is a managed Apache Kafka, the most popular streaming platform in the open-source world. It comes as provisioned clusters with Standard or Express brokers, or as Serverless.

Kinesis Data Streams Amazon MSK
Split into Shards Topics and partitions
APIs AWS's own Standard Kafka
Record size 1 MiB by default, up to 10 MiB 1 MB by default, and configurable
Choose it if You want the simplest option on AWS You have Kafka applications and tools

How does the data arrive?

Choosing a way in starts with how often the data arrives, and how large it is:

The data Use
Files from a server or NAS, on a schedule DataSync
Files from partners over SFTP Transfer Family
Small records, continuously, with several readers Kinesis Data Streams or MSK
Small records, continuously, landing in storage Data Firehose
Rows changing in a database Zero-ETL or DMS
Data sets from other companies AWS Data Exchange, where you subscribe to them

Secure each way in the same manner: least-privilege IAM roles, encryption in transit and at rest, and private paths such as VPC endpoints instead of the public internet where you can.

The complete picture

Here's how the pieces meet in a typical pipeline:

Sources Apps and logs Firehose Collects S3 Raw data Glue Cleans, converts S3 Parquet Athena Answers with SQL Quick Sight Dashboards Your team Decides
Data lands raw in S3, Glue converts it to Parquet, Athena answers from it and Quick Sight displays the result. Redshift can take Athena's place for heavy reports.

Hands-on: Parquet cuts what a query reads

We'll generate a file of 200,000 orders and put the same question to it twice. From CloudShell:

Bash
BUCKET=series-data-$RANDOM$RANDOM
aws s3 mb s3://$BUCKET

awk 'BEGIN {
  srand(7)
  split("Riyadh Jeddah Dammam Abha Tabuk", city, " ")
  for (i = 1; i <= 200000; i++)
    printf "%d,%s,%d,%.2f\n", i, city[int(rand()*5)+1], 2024+int(rand()*3), rand()*500
}' > sales.csv

head -3 sales.csv
aws s3 cp sales.csv s3://$BUCKET/raw/sales.csv

This function runs a query, waits for it, then prints its state, the bytes it scanned and its result:

Bash
run_sql() {
  ID=$(aws athena start-query-execution --query-string "$1" \
    --result-configuration OutputLocation=s3://$BUCKET/results/ \
    --query QueryExecutionId --output text)
  while true; do
    STATE=$(aws athena get-query-execution --query-execution-id $ID \
      --query QueryExecution.Status.State --output text)
    [ "$STATE" = QUEUED ] || [ "$STATE" = RUNNING ] || break
    sleep 1
  done
  aws athena get-query-execution --query-execution-id $ID \
    --query "QueryExecution.[Status.State,Statistics.DataScannedInBytes]" \
    --output text
  aws athena get-query-results --query-execution-id $ID \
    --query "ResultSet.Rows[*].Data[*].VarCharValue" --output text
}

Describe the file as a table. Nothing moves, and the data stays in S3:

Bash
run_sql "CREATE DATABASE series_data"

run_sql "CREATE EXTERNAL TABLE series_data.sales_csv (
  order_id INT, city STRING, year INT, amount DOUBLE
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION 's3://$BUCKET/raw/'"

Ask the question:

Bash
run_sql "SELECT city, ROUND(SUM(amount)) AS total
FROM series_data.sales_csv WHERE year = 2025
GROUP BY city ORDER BY total DESC"

You get the total for each city, and the first line shows the whole file was scanned, a little over 5 MB, even though the question concerns one year and two columns. Now create a partitioned Parquet copy with one query:

Bash
run_sql "CREATE TABLE series_data.sales_parquet WITH (
  format = 'PARQUET',
  external_location = 's3://$BUCKET/parquet/',
  partitioned_by = ARRAY['year']
) AS SELECT order_id, city, amount, year FROM series_data.sales_csv"

aws s3 ls s3://$BUCKET/parquet/

You'll see a folder for each year. Ask the same question of the new table:

Bash
run_sql "SELECT city, ROUND(SUM(amount)) AS total
FROM series_data.sales_parquet WHERE year = 2025
GROUP BY city ORDER BY total DESC"

The numbers match, but the scanned bytes are a small fraction of the first figure. On terabytes, that difference is your bill.

Bash
run_sql "DROP TABLE series_data.sales_parquet"
run_sql "DROP TABLE series_data.sales_csv"
run_sql "DROP DATABASE series_data"
aws s3 rb s3://$BUCKET --force

Summary

  • Separate analysis from your production database, and store data by column.
  • Athena queries S3 with no servers, and Parquet and partitions lower its cost.
  • Redshift is for heavy, repeated reports, and Serverless is an easy start.
  • Glue catalogs and converts your data, and Lake Formation controls who sees which column.
  • OpenSearch is for search, EMR for Spark jobs, Quick Sight for dashboards, and Flink and MSK for streams.

Test yourself

Before you move on, try these questions to check you've got this part. Each one is a practical scenario, and the explanation appears once you answer.

Question 1 of 6

A retail chain's analysts run heavy reports all day, with many joins across years of sales, and dozens of dashboards refresh from them. Which service was built for this?

Show the answer

Correct answer: C

This is a data warehouse's job. Redshift stores data by column and splits each query across many nodes, so heavy, repeated reports run fast.

  • A: This suits occasional questions, and with this many queries you'd pay for every scan.
  • B: This takes load off production, but it still stores data by row and isn't built for this scale of analysis.
  • D: This is for text search and log analysis.

Review: Athena or Redshift? in this part, and What is Amazon Redshift? in the AWS docs.

Question 2 of 6

Partners drop CSV files into an S3 bucket every day. A team wants them converted to Parquet on a schedule, with no servers to run and without reprocessing files already converted. What fits?

Show the answer

Correct answer: A

A Glue ETL job runs Spark with no servers to manage, and job bookmarks remember what's been processed, so each run handles only the new files.

  • B: A crawler works out the columns and updates the catalog, and doesn't convert anything.
  • C: This could do the conversion, but it's a cluster you'd have to run.
  • D: This moves files between classes, and doesn't change their format.

Review: AWS Glue: preparing the data in this part, and Tracking processed data using job bookmarks in the AWS docs.

Question 3 of 6

A company's data lake holds an orders table in S3, queried through Athena. The sales team must see the table, but not its card number column. What fits?

Show the answer

Correct answer: D

Lake Formation grants access down to the column and row, and those permissions apply through services like Athena.

  • A: S3 knows about files, not the columns inside them.
  • B: A crawler only describes the data, and controls nobody's access.
  • C: This gives a team its own door to a bucket, and still works at the level of files.

Review: Lake Formation: permissions for the lake in this part, and Data filtering and cell-level security in Lake Formation in the AWS docs.

Question 4 of 6

A store keeps its products in DynamoDB. Customers want to search for any word in a product's name or description, and the table must stay the source of truth. What fits?

Show the answer

Correct answer: B

OpenSearch finds any word in any field. Streams and Lambda keep it up to date, so you search there, then fetch the full item from the table.

  • A: An index finds items by key, not by any word inside a long text.
  • C: This reads the whole table for every search, so it's slow and costly.
  • D: This speeds up reads by key, and adds no text search.

Review: OpenSearch in this part, and Loading streaming data into Amazon OpenSearch Service in the AWS docs.

Question 5 of 6

A team's Athena bill is high. Its queries usually read two columns from one month of data, but everything sits in S3 as one big folder of CSV files. Which two changes lower the cost? (Choose two.)

Show the answer

Correct answer: B + E

Athena charges for the data it scans. Parquet lets a query read only its columns, and partitions let it skip the other months.

  • A: Files in this class have to be restored before they can be read.
  • C: The price depends on what's read, not on when.
  • D: This keeps old versions, and changes nothing about what a query reads.

Review: Read less, pay less in this part, and Use columnar storage formats and Partition your data in the AWS docs.

Question 6 of 6

An analytics team wants weather data from a commercial provider in its data lake, kept current through a subscription, without building a custom feed. What fits?

Show the answer

Correct answer: A

Data Exchange is where you find other companies' data sets and subscribe to them.

  • B: This receives files over SFTP and the like, so the provider would still have to send them to you.
  • C: This describes data you already have, and doesn't bring in new data.
  • D: You'd have to write what feeds it, which is the work the team wants to avoid.

Review: How does the data arrive? in this part, and What is AWS Data Exchange? in the AWS docs.

You now understand the data you hold. Can you get more out of it, such as reading documents, understanding speech or generating text? In part twenty-four we go through AWS's ready-made AI services.