Find October's logs among a million files
S3 object storage keeps files as objects in a bucket, and you find them by name. Knowing how to list a bucket by the start of a name saves you reading every file.
A shop saves its web logs in an S3 bucket, one file a day for years. You want only the logs for October. Opening a million files is out of the question. S3 can list only the files whose names start a certain way.
By the end of this lesson
Note
I can find files in a bucket by prefix.
Key words
| Word | What it means | Example |
|---|---|---|
| Object | one stored file and its details | |
| Key | the full name of an object in a bucket | logs/2026-10-01/web.log |
| Prefix | the start of a key | |
| Delimiter | a character that splits a key into levels | / |
| Common prefix | a folder-like start that several keys share |
The cells students fill in are left blank in this preview.
A bucket holds objects, each with a key
A bucket holds objects. An object is the bytes of a file plus details such as its size. Each object has a key, its full name, and the key is how you find it.
There is no tree of folders inside. The bucket is one flat list of keys. A key such as logs/2026-10-01/web.log is just a long name that contains slashes.
Run: read a listing
answer = {
"Name": "shop-logs",
"Prefix": "",
"KeyCount": 4,
"IsTruncated": False,
"Contents": [
{"Key": "images/cat.png", "Size": 4, "StorageClass": "STANDARD"},
{"Key": "logs/2026-10-01/web.log", "Size": 17, "StorageClass": "STANDARD"},
{"Key": "logs/2026-10-02/web.log", "Size": 6, "StorageClass": "STANDARD"},
{"Key": "readme.txt", "Size": 5, "StorageClass": "STANDARD"},
],
}
for item in answer["Contents"]:
print(item["Key"], item["Size"])
# Add up the Size of every object and print the total.
A common mistake
Warning
Many people think an S3 bucket has real folders. It does not. The slash is only a character in the key. A folder appears in a listing only because several keys start the same way, and it vanishes when its last object is deleted.
A prefix lists keys that start with it
When you list a bucket you may pass a prefix. S3 then returns only the keys that start with it. The prefix logs/2026-10-01/ finds one day of logs and nothing else.
S3 does the filtering, so your code never has to read the whole bucket. The answer repeats the prefix you sent and counts the keys found in KeyCount.
Run: filter keys by prefix
keys = [
"images/cat.png",
"logs/2026-10-01/db.log",
"logs/2026-10-01/web.log",
"logs/2026-10-02/web.log",
"readme.txt",
]
prefix = "logs/2026-10-01/"
found = []
for key in keys:
if key.startswith(prefix):
found.append(key)
print("KeyCount:", len(found))
print(found)
# Change prefix to "logs/" and press Run. How many keys now?
A delimiter groups keys into folders
Say you want the folders directly under logs/, not every file. Pass the delimiter / as well as the prefix. S3 cuts each key at the first slash after the prefix.
Keys that share a cut-off are returned once, as a common prefix, in CommonPrefixes. Keys with no slash after the prefix come back in Contents as before.
Run: find the folders under logs/
keys = [
"logs/2026-10-01/db.log",
"logs/2026-10-01/web.log",
"logs/2026-10-02/web.log",
]
prefix = "logs/"
common = []
for key in keys:
rest = key[len(prefix):]
slash = rest.find("/")
if slash != -1:
folder = prefix + rest[:slash + 1]
if folder not in common:
common.append(folder)
prefixes = []
for one in common:
prefixes.append({"Prefix": one})
answer = {"Prefix": prefix, "Delimiter": "/", "CommonPrefixes": prefixes}
print(answer)
# Add the key "logs/2026-10-03/web.log" to keys. Run again.
Missing keys answer in two ways
Asking for one object that is not there is an error. The two calls differ. get_object answers with the Code NoSuchKey. head_object, which only asks for the details, has no body to hold a name, so its Code is "404".
Both have the status 404. Test the status when you want to cover both.
Try it in the cloud lab
The cloud lab is a practice copy of S3, SQS and DynamoDB. Press Start the lab on the bar, then press Run on each command below. They use the real AWS command line, so the same words work on a real account. The last two commands show a listing with the folder logs/2026-10-01/ in CommonPrefixes, and then the error NoSuchKey. This step is for practice. The assignment below stays plain Python, so you can do it without the lab.
Set a made-up key and the lab's address
export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test AWS_DEFAULT_REGION=us-east-1 AWS_ENDPOINT_URL=http://cloud:4566Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Make a bucket
aws s3 mb s3://prefix-labShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Store an object under a key with slashes
aws s3 cp /etc/hostname s3://prefix-lab/logs/2026-10-01/web.logShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
List with a prefix and a delimiter
aws s3api list-objects-v2 --bucket prefix-lab --prefix logs/ --delimiter /Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Ask for a key that is not there
aws s3api get-object --bucket prefix-lab --key nothing.txt /dev/nullShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.