Categories
Data & Analytics

Building An AWS Garmin Data Pipeline For My Charity Marathon

I’m running the Chester Marathon for charity to support Pendleside Hospice! In this post, I build an AWS data pipeline to analyse my Garmin training data.

Introduction

Outside of my AWS and community work, I have several hobbies – one of which is running. I was a big running fan in the 2010s, and after a few years away I got back into it in 2025. I’ve had a pretty decent 18 months with it, and this summer I decided to check off one of my bucket list items by running a marathon for charity.

A side effect of my marathon training has been an influx of training data. While I already have access to platforms like Garmin Connect and FetchEveryone to analyse this data, neither platform quite gives me the full picture I want. My choices were to either pay Garmin for enhanced features or build an AWS Garmin data pipeline. And I’m not one to turn down a good data project!

Firstly, I’ll cover how the data is generated and collected. Then I’ll walk through the three-account AWS architecture that turns the raw files into data a Bedrock agent can analyse. Finally, I’ll cover what that agent actually found after I pointed it at my training data.

Future posts will examine the backend behind each pipeline stage. This one’s about the shape of the whole pipeline and the race it was built for. Let’s begin by looking at my chosen charity.

The Charity

Pendleside Hospice is a registered charity based in Burnley. Founded in 1988, they provide palliative and end-of-life care for people across Burnley, Pendle and Rossendale. They originally focused on cancer care, but now support people with a wider range of life-limiting conditions, including dementia, respiratory and neurological illnesses.

Pendleside have cared for a good friend of mine. Martine Hamer worked alongside her husband Russell at his Burnley salon. Russell’s been cutting my hair for over two decades, and Martine was the one who mixed the bleach, ran the hairdryers and occasionally talked me into a spray tan. After her short battle with breast cancer, she died in Pendleside’s care in February 2010, aged just 35.

MartineHamer

Pendleside cares for over 1,700 people every year across a 10-bed inpatient unit, a Hospice at Home service, day therapy and bereavement support for families and children. They also run a Meals on Wheels service and a Health, Wellbeing & Rehabilitation programme that offers services such as physiotherapy and counselling.

Operating Pendleside requires over £4.5 million a year. An NHS grant covers around 20% of that, leaving over £3.5 million to be raised each year locally through events, their charity shops and donations.

I’ve fundraised for Pendleside before, doing the 2010 Bupa Manchester 10k for them. But there was always something else in the back of my mind…

The Marathon

I’ve thought about running a marathon for charity several times over the years, but never felt right doing it when I was frequently running a couple of them a year. After all, if I was doing that many, where was the challenge? Having had an extended break and several life changes, 2026 feels like the ideal time to give it a go.

While this is my first charity marathon and my first one for a while, it’s not my first marathon. That honour falls to the wet, windy 2012 Manchester Marathon, which still lives in infamy in the minds of those who took part.

Amazingly, I came back for more after this! In the following years, I ran various marathons, including locally in Manchester and in the capital, through vineyards at the Marathon du Médoc and around a running track at the Groundhog Marathon.

MBNA Chester Marathon 5983006 121918 Finish 600

This came to a stop, like many things, during the 2020 pandemic. Running then took a back seat for a few years until I got back into it in 2025 after joining the Steamhaus Vitality scheme. Fast forward 18 months, and I find myself with an entry for the 2026 Chester Marathon and the opportunity to finally fundraise for Pendleside.

I’ve done Chester twice before, in 2013 and 2019. There are a few reasons for choosing it for my 14th marathon:

  • Chester is a lovely city, and the route is fantastic and well supported.
  • The Active Leisure team is a great event organiser with over a decade of experience.
  • The last running event I did pre-pandemic was the 2020 Chester 10k. So spiritually, this feels like I’m picking up where I left off.

If you’d like to support Pendleside Hospice, you can do so through my JustGiving page.

Data Collection

In this section, I’ll explain where the Garmin data in the AWS pipeline comes from: what captures it, what’s actually captured and the format it arrives in.

Device

My current watch is a Garmin Forerunner 745, a mid-range running and triathlon watch that sits between the Forerunner 645 and the Forerunner 945. It tracks everything I need for marathon training: GPS position, heart rate, pace and cadence. It also has a pulse oximeter for blood oxygen, a barometric altimeter and onboard training load and recovery metrics.

Upon completion, activities are uploaded to Garmin Connect via my phone’s Bluetooth.

Garmin Connect

Garmin Connect is the companion platform for data collected by Garmin devices. Activity, health and training data are automatically uploaded here after device syncing. Garmin then turns this data into various reports, visuals and feedback. These can range from the pace and heart rate zones of individual activities to aggregated training loads and historical mileage.

Garmin Connect hero image 1480x975

Crucially for this project, it also lets me download the data in various formats, including the raw FIT files that everything else in this pipeline depends on.

FIT Files

Flexible and Interoperable Data Transfer (FIT) is the file format Garmin devices use to record and share activity data.

Rather than storing one big block of numbers, a FIT file is built from streams of timestamped messages. These capture the same GPS, heart rate and cadence data as the watch itself, plus other data like power and speed, all streamed as the activity happens rather than saved as a single summary.

It’s compact and self-describing by design, making it ideal for Garmin Connect and other training platforms like Strava, TrainingPeaks and FetchEveryone.

Architecture

This section examines the multi-account architecture of the AWS Garmin FIT data pipeline. I discuss the concept of a multi-account strategy and its benefits, then examine each account’s role in the data pipeline.

Multi-Account

Before getting into what each account actually does, it’s worth explaining why this pipeline is split across multiple accounts in the first place.

Multi-Account Strategy

A multi-account strategy is the practice of splitting workloads, environments and admin boundaries across multiple AWS accounts. Each account has a specific, well-defined role, rather than relying on IAM policies or resource tagging for separation inside a single account.

Where a single account relies on carefully maintained policies to keep teams, systems and environments separate, a multi-account strategy makes that separation structural. Each account becomes its own hard boundary instead of a policy-enforced one.

The strategy typically extends beyond individual workloads to environments, products and business areas, and is usually managed centrally through AWS Organizations.

But why bother? What benefits does a multi-account setup offer?

Multi-Account Benefits

AWS has a white paper on this – Organizing Your AWS Environment Using Multiple Accounts. And while it’s aimed at enterprise customers, many of the benefits it covers apply just as well to my multi-account AWS Garmin data pipeline architecture.

Data Access Controls: I’ve worked with data for many years, and ensuring the right data is in the right place and accessible to the right people is a common challenge. AWS accounts are ideal boundaries to resolve this, offering strict access controls and enforcing one-way data flow at the account level. This means, for example, that a Lakehouse process can never overwrite raw data in the Data Lake, and an AI process can only read Lakehouse data that’s been cleansed and curated.

Blast Radius Limitation: Things break, and things fail. When that happens and everything lives in the same account, it can be disastrous. A multi-account setup has inherent boundaries that limit the scope of adverse events such as misconfigurations, compromised credentials or bad deployments.

Grouping By Purpose: Splitting workloads into separate accounts means I can manage them on their own terms without creating unnecessary or unintended dependencies. This separation also ringfences each account’s use of services, quotas and billing, making scaling up far simpler.

Pipeline Accounts

This section reviews each AWS account of the Garmin data pipeline. First is the Data Lake account, where raw data lands and is stored. Next is the Lakehouse account, which cleanses and curates the data. Finally is the AIML account, which analyses the curated data for insights.

Data Lake Account

This account is a landing zone. Its main job is to capture and store raw data and grant read-only cross-account access to it.

It currently holds two S3 buckets: one for sensitive data and a general-purpose one for everything else. Data here is version-controlled, immutable and easy to locate and back up. Data is currently added manually, but over time this will expand to include ingestion scripts that pull data from third parties, as well as automated pushes from agents and IoT sensors.

Lakehouse Account

This account transforms and serves data. It owns the ELT pipeline, the transformed data storage, the Glue Data Catalog and the Athena workgroup. The Lakehouse has Cleansed, Curated and Semantic layers, with further separation for sensitive and general data classifications.

While the Lakehouse account can access both Data Lake buckets, access is scoped per process rather than granted fully. The AWS Garmin data pipeline’s ELT processes can only access the general bucket, as they don’t need anything from the sensitive one. The AIML account’s access works on the same principle of least privilege, using a separate cross-account role scoped to a single Glue database, S3 prefix and Athena workgroup.

AIML Account

This account consumes data from the Lakehouse account for GenAI processes. It owns a Bedrock agent, two Lambda functions and its own S3 buckets for query results and generated output.

The AIML account queries data in the Lakehouse account through its Glue Data Catalog. It has no access to the Data Lake account and cannot read data that has not already passed through the Cleansed and Curated Lakehouse layers. This ensures the agent uses only validated, trusted data.

Processes

This section covers what actually happens at each stage of my AWS Garmin data pipeline: the triggers, the hand-offs and the grants the accounts use to interact with each other.

There are three AWS accounts in the Garmin data pipeline, each of which owns separate processes:

CharityBlog AWSAccounts.drawio
  • Data landing and storage in the Data Lake account.
  • Data cleansing and curation in the Lakehouse account.
  • Analytics and report generation in the AIML account.

Data Lake Account

data lake storage account architecture dark

Garmin data as FIT files enters the raw-general S3 bucket by manual upload. The account then answers read requests from the Lakehouse’s Cleansed ELT Lambda, granted via bucket policy. There is no processing, no deletion and no outbound calls initiated from this account.

Lakehouse Account

lakehouse account architecture

The Lakehouse account owns two distinct processes:

  • The Cleansed process, which converts the raw FIT files into readable Parquet data.
  • The Curated process, which validates the data and derives new columns to add value.

Cleansed Process

garmin cleansed pipeline stepfunctions graph

An EventBridge Scheduler runs a cron trigger every day at 06:00 UTC, which starts a Step Function. In the first step of this execution, an S3 List step reads the contents of the Garmin folder in the Data Lake account’s raw-general S3 bucket.

Next, the Cleansed Filter Lambda checks each FIT object against those already processed and passes along the unprocessed ones. Then a Map state fans out across these objects, running the Cleansed ELT Lambda once per object with a maximum concurrency of ten.

Each ELT invocation pulls its FIT file directly from the Data Lake account, using bucket-policy-granted access on the Lambda’s execution role. It then decompresses the file and parses the FIT binary with garmin-fit-sdk.

From there, it converts FIT epoch timestamps into standard datetimes and semicircle coordinates into decimal-degree latitude and longitude, then writes the results as Parquet files to the Cleansed bucket. 21 tables are written per activity, with partitions and table schemas registered or updated in the Glue Data Catalog.

Curated Process

garmin curated pipeline stepfunctions graph

When the Cleansed Step Functions execution succeeds, an EventBridge Rule triggers a second state machine for the Curate process.

In the first step of this execution, a Curated Filter Lambda identifies activities that have not yet been promoted by checking whether curated output already exists. Then a Choice state checks if everything is up to date. If it is, no further action is taken. If not, a Map state fans out across the unprocessed files, invoking the Curated Promote Lambda for each activity with a maximum concurrency of ten.

Each Curated Promote Lambda invocation reads its assigned Cleansed Parquet file for all 21 tables and computes derived features on the records table: elapsed seconds, cumulative distance, grade percentage, pace (min/km) and heart-rate zone. It then validates every table row against a corresponding Pydantic schema and writes valid rows to the Curated bucket. The Curated tables are registered in a separate Glue database.

Reliability & Access

Idempotency is handled at multiple points in both processes:

  • The Cleansed Filter Lambda won’t include a file in the Map state if its output already exists.
  • Cleansed ELT Lambda invocations perform their own HeadObject check before writing, in case two invocations race each other.
  • Curated Filter and Promote Lambdas apply the same output-exists pattern against the Curated bucket.

Additionally, CloudWatch alarms trigger if any Lambda invocation errors out.

Once the Curated tables are registered, the AIML account can query them via Athena. A cross-account GarminDataCrossAccountReadRole IAM role is assumable by the AIML account’s Garmin Agent Lambda, and grants the following:

  • Read access to the Curated Glue database.
  • Read access to the S3 prefix where those tables live.
  • Use of a dedicated garmin-agent-queries Athena workgroup with an enforced output location.

Results land in a separate athena-results S3 bucket in the Lakehouse account, kept apart from the process’s own working buckets.

AIML Account

aiml account garmin agent architecture

Two separate flows run here. In the interactive flow, a user prompt is sent to the marathon-training-analyst Bedrock Agent, running on Claude Sonnet. The agent interprets it and calls one of six endpoints in the query Lambda’s action group depending on the prompt, covering topics such as training summaries, activity details, heart rate trends and pace trends.

The Query Lambda then assumes GarminDataCrossAccountReadRole in the Lakehouse account via AWS STS and runs an Athena query against the Curated Glue database, scoped to the garmin-agent-queries Athena workgroup. It converts the raw metrics (m/s to min/km pace, metres to km, seconds to H:MM:SS) and returns structured results to the agent, which formats a natural-language response.

In the batch flow, the Orchestrator Lambda calls the same agent with a comprehensive analysis prompt that explores topics such as volume progression, pace trends and race predictions. It collects the agent’s streamed multi-step reasoning and query results, combines them into a Markdown document, and writes the finished output to the genai-results bucket where it’s picked up for personal use.

AIML Agent Prompt

For completeness, I wanted to briefly discuss the marathon-training-analyst agent’s prompt. I won’t include the full prompt here for two reasons:

  • It’s been superseded by a newer version, which I’ll discuss later.
  • The prompt is over 220 words long, so focused sections will be easier to follow than the whole.

So here is an abridged version of what the agent gets when the batch flow runs. I’ve removed some of each section’s bullets – the remaining text is unaltered:

“You are an expert marathon running coach and sports data analyst. You have access to a runner’s Garmin training data and your job is to analyse their marathon preparation.

When analysing training data:

  • Calculate and interpret weekly mileage progression, noting appropriate buildup and recovery weeks
  • Identify injury risk factors: sudden volume spikes (>10% week-over-week), insufficient rest days
  • Provide race day predictions using established methods (Jack Daniels formula, pace-based estimates)

When producing output:

  • Lead with key insights, support with specific numbers from the data
  • Use markdown formatting with headers, bullet points, and emphasis
  • Include specific dates, distances (in km), paces (min/km), and heart rates where relevant

Always query the data before making claims. Do not hallucinate metrics — use only what the data shows.
Garmin speeds are in m/s — convert to min/km for display (pace = 1000/60 / speed_m_s).
Distances in the data are in metres — convert to kilometres for display.”

Isn’t This All Overkill?

A fair question to end on. And yes – this would be total overkill if all I was planning to do with this was the Garmin analysis.

But each of these accounts has more work ahead of it. There will be new ingestion processes in the Data Lake account, new databases in the Lakehouse account and new agents in the AIML account. Indeed, this exact framework will now be receiving Project Wolfie data in the coming months!

The intention behind this architecture is to build something I can use long-term. While it may seem like a lot of work and resources for such a small project, the more time I spend on it now, the more likely it is to support my future requirements.

And that’s the AWS Garmin data pipeline! Three accounts and a lot of careful plumbing, taking raw FIT files and transforming them into queryable data. So what did those 28 weeks of training data actually say?

Tests & Insights

In this section, I’ll go through what the Bedrock agent found when it analysed my Curated dataset generated by my AWS Garmin data pipeline, covering 28 weeks and 66 running activities totalling 573 km.

A brief caveat. These findings are from a version of the agent that has since had some tweaks and changes. These findings remain valid, and I’ll explore the agent’s changes in future posts.

Let’s start with pace trends. This is how pace and heart rate interact across different types of runs. This is important because pace alone isn’t the whole story.

Running at a certain speed with a low heart rate is a very different signal from running at the same speed with a high one, and comparing the two over time is one of the clearest ways to see whether training effort is being optimally controlled. Two of the most suitable run types for this analysis are easy runs and quality sessions.

Easy runs are deliberately slow, low-effort miles that build an aerobic engine without piling on fatigue. The goal here isn’t speed – it’s staying comfortable enough to hold a conversation. The heart rate range that keeps a run ‘easy’ is often called Zone 2, calculated in my case via Heart Rate Reserve rather than straight % max, at roughly 60-70% of HRR. For me, this currently falls somewhere between 145 and 165 BPM.

Quality sessions are structured, harder efforts such as tempo runs or threshold work. These target a specific pace range to build speed and the ability to sustain effort under fatigue.

Pace Findings

The Bedrock agent reported that the easy runs were suitably paced. The bulk of the shorter runs fell in the 5:15-5:35/km range at 145-165 BPM, comfortably within the Zone 2 window. For example:

  • On 17 January, I ran 6.85 km at 5:19 pace and 147 BPM.
  • 08 May: 5.7 km at 5:33 pace and 149 BPM.
  • 17 June: 5.6 km at 5:31 pace and 147 BPM.

Across the 28 weeks, easy days stayed easy – exactly what they’re supposed to be.

Pace Concerns

Bedrock flagged some inconsistencies across quality sessions. Four key tempo efforts sat in a tight 10-second pace band (4:46/km-4:56/km), but their average heart rates ranged from 161-177 BPM. This is a 16 BPM spread for nearly identical effort outputs.

The agent saw that spike as either a sudden loss of aerobic fitness or poor effort control. In reality, that spread was driven mostly by this summer’s heatwaves, during which thermal stress artificially elevated my heart rate.

This highlights a gap in my initial dataset. Because FIT files don’t record ambient weather, Bedrock was analysing telemetry with insufficient context. Ingesting weather API data into the pipeline could resolve this in future analysis.

Volume Progression

Next, volume progression: the increasing weekly mileage a training plan builds toward race day. This is the main way to build endurance…and also a frequent cause of injury! Push the weekly total up too slowly, and marathon day will arrive without a sufficient endurance base. Push it too fast, and the body doesn’t have time to adapt to the added load.

Volume Findings

The Bedrock agent reported that my Garmin dataset shows textbook periodisation. A gradual climb with deliberate peaks and recovery weeks placed where they were needed. The buildup from 16.94 km in the week of 1 February to 37.63 km in the week of 27 April took 12 weeks, which is an acceptable progression.

Recovery weeks were also well-scheduled. The week of 4 May dropped to 27.8 km (-26%) straight after the 37.63 km peak, and the week of 1 June dropped again to 25.35 km (-40%) after a second peak of 41.93 km. That second recovery week came right before one of the training block’s biggest pushes: 47.13 km in the week of 8 June, a 12.4% rise from the 25 May peak.

Volume Concerns

For volume progression, a commonly cited guardrail is the 10% rule: don’t increase weekly mileage by more than about 10% from one week to the next. The analysis found that two weeks broke this rule.

The week of 27 April saw a 66% jump from 22.66 km to 37.63 km. The week of 8 June went further, up 86% from the previous week’s 25.35 km to 47.13 km. Both are the kind of single-week spike that usually precedes an injury. The recovery weeks before each spike mitigated some of the risk, but it’s not something to make a habit of!

Race Prediction

Bedrock modelled my estimated marathon time three separate ways:

Method 1: Training Pace Analysis

This method works backwards from recent hard efforts. Firstly, identify the pace I can hold at lactate threshold. Then apply the well-established rule that marathon pace is roughly 8-10% slower than threshold pace, since race effort must be sustained for hours rather than minutes.

Recent quality sessions:

  • 30 April: 8.18 km at 4:54/km, 170 BPM (threshold)
  • 17 May: 22.54 km at 5:06/km, 169 BPM (marathon pace simulation)
  • 11 July: 9.84 km at 4:56/km, 177 BPM (near-threshold)

Bedrock estimate: These paces suggest:

  • Threshold pace: ~4:54-4:56/km
  • Marathon pace (8-10% slower than threshold): 5:18-5:26/km
  • Predicted finish: 3:43-3:49

Method 2: Heart Rate Efficiency Model

This method uses heart rate rather than pace as the anchor: it looks at what percentage of max heart rate can be sustained over a race-length effort, then finds the pace that sits in that same effort zone across the full marathon distance.

I can currently sustain 5:04/km at 170 BPM for 32.22 km. Given:

  • Max HR appears to be 193-196 BPM.
  • 170 BPM = ~87-88% max HR (solid marathon effort zone).
  • Cardiac drift is minimal on long runs.

Conservative marathon pace: 5:20-5:25/km at ~170 BPM.

Predicted finish: 3:45-3:49

Method 3: Jack Daniels VDOT

VDOT is a single number that Jack Daniels’ running formula uses to represent overall running fitness. It combines aerobic capacity (VO2max) with running economy (how efficiently oxygen is used) into one score derived from an actual race performance. That score is then used to predict equivalent times at other distances.

The 22.54 km at 5:06/km (1:54:59) suggests a VDOT of approximately 39-41.

  • VDOT 40: Predicted finish = 3:49:45
  • VDOT 41: Predicted finish = 3:45:00

Consensus Prediction

All things considered, Bedrock currently estimates my finish time at 3:45-3:49 (5:18-5:26/km), basing this on:

  • Peak long run of 32.22 km demonstrating distance readiness.
  • Easy runs were reliably held within the Zone 2 range, indicating well-controlled training intensity.
  • Recent quality work (11 July at 4:56/km) showing retained speed.
  • Total volume of 573 km over 28 weeks is solid marathon preparation.
  • Long runs executed at appropriate aerobic effort.

Personally, this feels optimistic. I was targeting closer to four hours, and my Garmin currently estimates a marathon time of 3:57. But this isn’t a short race – minutes of drift in estimates are common in endurance events like the marathon.

Bedrock sensibly includes caveats in its analysis. The race outcome heavily depends on factors including:

  • Weather conditions: Heat, rain and wind all significantly impact performance.
  • Pacing discipline: Going too fast in the first half will burn energy needed for the second half.
  • Nutrition and hydration: Strategy in the week of the event and on the day matters just as much as fuelling during the race itself.
  • Taper quality: Tapering too soon or too late can affect marathon readiness.

Summary

This project started as a way to make additional use of my Garmin training data, and became a three-account AWS data pipeline: raw FIT files landing in the Data Lake account, being cleansed and curated in the Lakehouse account and then handed to a Bedrock agent in the AIML account for analysis. Along the way, that agent told me things about my training I hadn’t noticed myself, some encouraging, some…not!

This is very much in the early days of the project, and there’s still plenty to work on. The agent needs more testing and refinement to improve analysis consistency, the code needs a proper review, and Data Lake FIT uploads are still something I do by hand rather than automatically. Future posts will get into all of that.

This project’s brought together a personal hobby and a professional one, and it’s been genuinely satisfying to build. I’ll keep tinkering with it between now and October, race day permitting.

If you’d like to support Pendleside Hospice, you can do so through my JustGiving page.

Like this post? Click the button below for links to contact, socials, projects and sessions:

SharkLinkButton 1

Thanks for reading ~~^~~

Categories
Training & Community

Supporting The Next Generation

In this post, I explain why I volunteer to give guest lectures for students and what supporting the next generation of developers, architects and engineers means to me.

Introduction

Opening LinkedIn one morning in June 2026, I was deeply touched to receive these kind and unexpected words from Ada‘s Steve Rich after my recent trip to sunny Sheffield:

2026 06 25 SteveAdaFeedback

I wasn’t initially sure how to respond without it turning into LinkedIn farming or a self-congratulatory fest, so writing about it here felt like the best option. I recently wrote some tips for anxious new panellists, and in a similar spirit this post seems like the best way to explain why I give these lectures and why I think they’re important.

Sure – it’s a good opportunity for me to practise and get out of my comfort zone. And as an AWS Community Builder and User Group Leader, I have access to tools and services that help me share knowledge and connect with the wider tech community. But there’s more to it than that, going back to my own experience studying technology in the early 2000s and why that motivates me to support today’s up-and-comers.

So in this post, I’ll talk about how I try to close the gap between the classroom and the real world. I’ll walk through what I did in Sheffield, and explain why supporting the next generation matters, both for Ada students and beyond.

About Ada

Firstly, some context about Ada:

AdaLogo

Ada, the National College for Digital Skills, is a specialist further education college founded in 2015 and named after Ada Lovelace. They offer Sixth Form and Apprenticeship curricula, have campuses in London and Manchester and also operate a cohort in Sheffield. Ada works with employers including AutoTrader, HSBC and Siemens, aiming to transform the lives of 10,000 young people by 2028.

Starting in 2024, I’ve done four lectures for Ada covering topics including cloud computing, data analytics and my career journey. What began as stepping outside my comfort zone has become a semi-regular thing! As someone active in the wider AWS community, through AWS User Group Lancashire and beyond, I’m hopeful I’ll get similar opportunities with Ada and other colleges and universities in the months and years ahead. I feel that supporting the next generation, wherever I can, aligns closely with the goals of the Community Builder and User Group Leader programs.

Making It Real

Let’s rewind to the early 2000s when I was studying. Studying technology was very different then than it is today. There was no Stack Overflow to read and interact with, no YouTube lectures and tutorials to watch and no Discord servers to share ideas and pool experience.

Instead, there were textbooks, demo files, PowerPoint slides and internet forums of varying quality. And despite my best efforts, my attention and enthusiasm slowly drained. I couldn’t see how I would use what I was learning in the real world. It wasn’t real, and I couldn’t find a way to make it real.

These were entirely my issues. Others I was studying with at the time went on to great things, but we don’t all learn in the same way, and that’s just how things panned out.

Fast forward twenty years, and that gap has closed in one sense. Today’s students have resources I couldn’t have imagined. But having more resources doesn’t necessarily solve the problem. What’s still missing is context: how all this stuff actually gets used, day to day, by people doing the job. That’s the gap I try to fill with my lectures – my own attempt at supporting the next generation to help them reach and thrive in the tech industry.

Opening It Up

The recent lecture I delivered for Ada in Sheffield is a good example of the kind of things I like to do. After getting a brief from Steve on what the students were studying, I built a simple real-time voting web app for the lecture. To make it interesting, the app used a shared frontend and database, but split its backend across three different AWS compute services – EC2, ECS, and Lambda – each with its own endpoint:

ada sheff architecture

My lecture had three parts. I began by discussing some core cloud concepts they’d touched on in class and which would soon come into play:

  • AWS Regions: Explaining what they are and how they address real-world concerns such as service latency, HADR and data sovereignty.
  • AWS Services: Exploring some of the service categories and explaining why AWS offer several services within each category.
  • Manual vs Managed: Discussing why managed services exist and exploring some of the high-level benefits and tradeoffs.

Then, I loaded up the app and let the students try it during a break.

In the second part, I broke the app down into its constituent pieces. I showed the architecture diagram and the CDK code, then accessed my AWS account and walked through everything: the shared CloudFront frontend and S3 storage, the different compute setups and even the Cost Explorer charts and CloudFormation deployment timelines.

This is something I rarely get to do in public, since most of my diagrams and code are subject to NDAs! This app was different – a bespoke build funded by my AWS Community Builder credits with nothing stopping me from opening it up to my audience completely. For the students, that meant a real AWS bill, a real deployment pipeline and real architecture decisions, not a sanitised slide-based classroom example.

The final part opened the floor for questions about the app, my Steamhaus role and anything else on their minds.

Making It Stick

I approach these lectures the same way I approach creating my AWS community sessions. Diagrams and slides will always have their place, but I prefer showing people what things actually do. When students can see a system working in the real world, it sticks in a way slides rarely do.

It’s also, in a small way, me helping these students with something I found hard while studying myself. I didn’t get any real-world examples, so I had to make do with what I could find and struggled as a result. If I can now reduce that burden for someone else, even by a lecture’s worth, that is time well spent.

Lectures like this aren’t easy to prepare, and they don’t always go to plan. But that’s kinda the point! Sometimes, neither does the job!

1782326784261
Mid-delivery @ Sheffield

Making It Accessible

When I was studying, there was always a question in the back of my mind that I couldn’t quite answer. What are the jobs like? What are the people like? What’s a typical day?

Without access to industry professionals it was impossible to know, and it’s easy to fill in those gaps with assumptions. And when your only experience of technology is via academia, you end up assuming the industry is full of academics.

The reality is very different. Yes, there are deep specialists who have been doing this all their lives. But there are also new starters, generalists, career-changers and everyone in between. This isn’t as obvious from the outside as it seems, so I try to improve the tech industry’s accessibility for students in two ways:

  • Bridging the gap between Levels 100 and 200.
  • Showing students that the people already doing the job are just as human as they are.

Levelling Up

Firstly, let’s talk about AWS levels. AWS uses a five-level scale to grade the audience knowledge expected of its talks, training and documentation. This ranges from Level 100 (Foundational) to Level 500 (Distinguished). It’s meant to help people find content pitched at the right depth for them, and help speakers and writers scope their material to a specific audience.

2026 07 19 AWSLevels

I’ve long held the opinion that there’s a missing layer between Levels 100 and 200 – and that’s where most students sit. There’s no exact science here, so I’ll use the AWS Community Day DACH Talk Levelling Guide for reference. It defines Level 100 audience knowledge as someone who might have heard of AWS but has little or no hands-on experience with it. Level 200 steps up to familiarity with the basics: spinning up resources and knowing core terms like VPC, EC2 and S3.

But going from not using AWS at all to spinning up AWS resources, and going from having limited knowledge of the public cloud to understanding the differences among networking, compute and storage services, are big leaps!

For example, students may be aware of AWS Regions but not understand their importance or utility. That understanding only really comes with real-world experience, and these students haven’t had the chance to build that yet. So a Level 100 session might teach them nothing new, while a Level 200 session might go over their heads.

I try to pitch my student lectures somewhere between. Expanding on the Level 100 fundamentals without assuming familiarity with Level 200 topics like containerisation, storage types and network subnets. It’s a tricky balance, and I don’t always get it right! But I aim to help them understand how services slot together for the kinds of things they’ll be doing in their careers. This understanding will, over time, help them manage resources and make their own architectural decisions, ultimately unlocking the myriad Level 200 and Level 300 materials that are widely available.

Keeping It Human

In our industry, there’s no always-right answer, and no answer without compromises or tradeoffs. I’m not a polished, gatekept authority handing down absolute truths. I’m just an engineer making things work.

This is why I prefer using an informal conversational style over a scripted, flawless “Here’s the correct solution” one. At Sheffield, I demonstrated the voting app in the same way I’d explain it to a colleague over coffee – mistakes, tangents and all.

Ultimately, if the students can see that this bumbling, slightly chaotic shark can make a half-decent go of things in the tech industry, then they should be emboldened enough to have a go themselves. To me, that’s what supporting the next generation is really about.

1726057746966
Talking about career beginnings in Manchester

Paying It Forward

Like many within the tech industry, my career is built on the generosity and patience of colleagues and strangers. Without these people, I wouldn’t be in the position I am today. I still remember the growing pains associated with triaging a ticket, using a Python virtual environment and being shown how to exit Vi for the first time. And the second time. And the thir…, well – you get the idea.

Looking back, the best seniors I worked with understood that mentoring isn’t a one-way street. When you guide someone, it builds momentum that helps them, and helps you too:

  • The learner gains confidence: They start taking initiative and solving problems independently.
  • The load gets shared: As they build confidence, they can take on operational workloads and build real, hands-on experience.
  • Your own knowledge gets stress-tested: You arguably don’t truly understand a concept until you have to explain it to someone else.
  • You grow as a leader: Teaching forces you to refine your communication, empathy and patience.

These principles also apply to lectures like the one in Sheffield. It’s not just information flowing one way from me to the students, but something that sharpens my own thinking too – supporting the next generation and myself at the same time.

The idea of paying it forward is central to our industry, whether from a screen, at a desk or in a classroom. There will always be people with experience to pass on, and people with things to learn. Now I’m in a position to pay it forward myself, handing on knowledge that took me decades to gather. So I’ll do what I can to keep this industry flywheel spinning.

1780601676178
Student Panel @ Comsum Birmingham

Summary

Twenty years ago, I didn’t have access to people working in the tech industry, and it would have made a real difference in the years that followed. Now that I’m in a position to be that person for someone else, I think it’s vitally important to make time for that.

Beyond the people I meet at conferences, meetups and user group events, there are entire generations of future developers, architects and engineers in classrooms around the world. And they’re all wondering what the industry holds for them. At a time of hiring uncertainty and AI-driven upheaval within the tech industry, supporting the next generation with honest, hard-earned advice is more necessary than ever.

Steve’s message is a good reminder of why all this is worth doing. If I don’t do it, who will? And if I do it often enough, and visibly enough, I’ll hopefully encourage others to do the same.

Like this post? Click the button below for links to contact, socials, projects and sessions:

SharkLinkButton 1

Thanks for reading ~~^~~

Categories
Training & Community

AWS DevOps Engineer Professional Exam Prep With Pepe Silvia

In this post, I share my experience passing the AWS DevOps Engineer – Professional exam, including study strategy, mock exams, time management and exam-day tactics.

Introduction

Back in March 2022, I wrote about passing the AWS Certified Developer – Associate certification. More recently, in May 2026, I took the AWS Certified DevOps Engineer – Professionalmy first AWS Professional certification.

I don’t usually write about exam prep — the strategies are personal, the technology moves fast, and there’s no shortage of good advice already out there. But I don’t see much written about the gap between the Associate and Professional certifications, so I thought I’d share my experience in this post.

First, I’ll examine some of those differences in detail. Then I’ll outline my study approach. Finally, I’ll share some survival tactics I used during the exam. And along the way, you’ll find out why one of my Steamhaus colleagues compared one of my strategies to the Pepe Silvia scene from It’s Always Sunny in Philadelphia.

pepesilvia
“Can we talk about the DevOps Pro please, Mac? I’ve been dying to talk about the DevOps Pro with you all day, okay?”

Professional vs Associate

This section explores some of the key differences between the AWS Associate and Professional certifications.

Before diving in, a quick note. Both AWS and Tutorials Dojo (which I’ll discuss later) offer excellent practice resources. While AWS still hosts older sample question PDFs (many of which haven’t been updated since 2022), the best place for their official materials is now the free tier of the AWS Skill Builder platform.

Scenario Length

The most obvious difference between the AWS Associate and Professional questions is length.

Professional exam questions are often much longer, sometimes two to three times as long as the Associate ones. And not all provided information is relevant. A major part of these exams is your ability to filter out noise and identify which constraints matter.

As evidence, look at this zoomed-out screenshot of Question 7 from the AWS DevOps Engineer – Professional sample PDF. I mean, LOOK AT IT.

2026 06 10 DOPQ7

It’s the entire page long! And, as I’ll discuss later, there’s not much time to read questions like these either. As for why many Professional questions are longer…

Knowledge vs Judgment

Associate questions generally check your understanding of what a service does. Professional questions assume you already know the technical terms and instead test your judgment over what actions to take.

To explore this, the Solutions Architect track offers the nearest like-for-like comparison. Let’s contrast Question 4 from the Solutions Architect – Associate sample exam questions:

2026 06 11 SAAQ4

With Question 3 from the Solutions Architect – Professional sample exam questions:

2026 06 11 SAPQ3

While the questions are thematically similar, they differ significantly in areas including:

Structure: The Associate question has a single correct answer. The Professional question requires two answers, each addressing a different layer of the architecture. This requires an understanding of how the services interact.

Scope: The Associate question focuses on a single service to solve a straightforward problem. The Professional question looks at the entire request pipeline: S3 serving the frontend, API Gateway handling the POST request and Lambda processing in the background. You must debug the whole system, not just choose the right service.

Detail: The Associate question provides only essential information. The Professional question includes additional elements that provide further context. It mentions that the team successfully tested each API method in the AWS console, which rules out server-side failures. Understanding this distinction is crucial for effective debugging.

Domain Structure

Associate exams focus on specific technical domains. Depending on the certification, these domains may include architectural best practices, development tasks or operational duties. Each domain is separate, making it easier to study and concentrate on one topic at a time.

Professional exams do not have clear boundaries. They require you to integrate knowledge from multiple domains at the same time, revealing something significant about what is actually being tested.

To see this in action, let’s look at the Solutions Architect track. The current version of the Solution Architect – Associate exam guide focuses on four domains:

  • Design Secure Architectures
  • Design Resilient Architectures
  • Design High-Performing Architectures
  • Design Cost-Optimised Architectures

These domains focus on the technical qualities of a workload. They closely align with the AWS Well-Architected Framework, and test the ability to identify the right services, apply best practices and recognise common design mistakes.

Conversely, the Solutions Architect – Professional exam guide takes a very different approach:

  • Design Solutions for Organisational Complexity
  • Design for New Solutions
  • Continuous Improvement for Existing Solutions
  • Accelerate Workload Migration and Modernisation

These domains are action-oriented and contextual, each specifying an action to perform rather than a quality to evaluate. They are open-ended and organisationally aware, rarely having a single correct answer.

Revision Strategy

This section explores my ways of preparing for the AWS DevOps Engineer Professional certification, including courses, mock exams and mental models.

Career Experience & Courses

2026 marks my tenth year working in technology, with the most recent two as an AWS Consultant at Steamhaus. While my day-to-day role naturally exposes me to several aspects of the DevOps Professional blueprint, it doesn’t cover all of them. That is where targeted courses come in.

I’m a longtime fan of Stephane Maarek, and had already bought his AWS DevOps Engineer – Professional Udemy course in a previous sale. The course covers a lot, but I felt less confident after finishing it than after his Associate courses. His DevOps course combines new lectures with material from his Associate courses. As a result, I found that some modules reinforced concepts I had already learned from the Associate-level material instead of providing the deeper context I wanted.

To fill the gaps, I used one of my Community Builder benefits – a free QA subscription. Danny Jessee‘s DOP-C02 preparation course covered similar topics to Maarek’s but delivered several lectures with the greater technical depth that I was seeking. The hands-on labs were also a massive help in demystifying some of the services and features I don’t often use.

With those gaps filled, it was time to start testing.

Mock Exams

Mock exams are likely the most valuable part of my study process. Since earning my first cloud certification in 2019, I have relied on the Maarek course and the associated Tutorials Dojo exams for each AWS certification.

Tutorials Dojo (TD) offers practice exams, cheat sheets and labs for several cloud certifications, including AWS, Azure and GCP. Each TD question bank has several modes, which I usually tackle in this order:

Section-Based: This mode focuses on specific topics and domains, giving the correct answer and a detailed explanation immediately after each question. This is great at flagging things I’ve misremembered, misunderstood or simply never touched, letting me refine my knowledge without burning through the question bank.

Review: This mode is more open-ended, posing questions from multiple domains. It isn’t timed and gives answers and explanations as before. I use this mode to build the mental stamina needed to answer large blocks of questions in bulk.

Timed: This mode mimics the exam. Questions are given under timed conditions, with a full report only upon completion. While some questions in the bank will now be familiar, this approach teaches me the strategies and timings I need for the actual exam.

After each session, I review the answers and identify topics and domains that are unfamiliar or problematic. What I do next with this knowledge has changed over the years…

Connecting The Dots

There’s no single correct way to use the results of a mock exam. Personally, I like to look for patterns in the areas where I’m struggling and connect them to topics I already understand.

For example, I was getting some ELB routing questions wrong, so I used my existing Route53 routing knowledge to fill in some gaps. I also had issues with some Elastic Beanstalk questions because I’m not a big user of the service, so I stepped away from the practice exams entirely to do a deep dive into the documentation and FAQs.

My goal isn’t to memorise answers. It’s to understand why an answer is correct well enough to recognise the same pattern in other questions. This eventually evolved into building mental models: connecting unfamiliar concepts to existing knowledge rather than collecting isolated facts. It’s an approach influenced by books like Make It Stick and How to Take Smart Notes, both of which argue that writing is a tool for understanding rather than simply recording information.

I like to write things down because it forces me to use my own words and highlights gaps in my understanding. It also encourages selectivity – since space is limited, every word must earn its place.

I’ve used several methods for this over the years, including:

  • Flashcard apps like Anki.
  • Ring binders with A4 notes and diagrams.
  • Blank A3 sheets as wall posters.

And now…

Pepe’s Whiteboard

Which brings us to my latest iteration and the reason for this post’s title – a whiteboard, several index cards and loads of fridge magnets:

DOPBoard600

While I could write directly on the whiteboard, the paper and magnets let me move, group, replace and reorganise cards without forcing a complete rewrite of the board.

This combines several benefits from the other systems:

  • Anki’s ease of note creation, tagging and movement.
  • The binder’s ease of writing notes on my own terms and in my own words.
  • The poster’s visibility and its ability to passively reinforce study material.

It also proved useful in the final days before the exam. Any cards that were still causing problems could be moved from the main board onto smaller, portable boards for targeted revision:

DOPBoardSmall600

This still has limitations, of course. It’s not portable as a complete knowledge source. The whiteboard also has limited space – in fact, I ultimately had to branch out to a nearby plastic box for overflow!

Despite the space constraints, I’m definitely a fan of this whiteboard approach and will use it for future exams. I might augment it with digital second brain tools like Obsidian or Google’s NotebookLM to inform what deserves a card, and I’ll be looking into this in the coming months.

Survival Tactics

This section examines some of my survival tactics for the AWS DevOps Engineer – Professional certification exam by optimising time, embracing personal kindness and checking my understanding.

The Maths is a Lie

The Professional exams have 75 questions with 180 minutes to answer them. This averages out at 2 minutes 24 seconds per question. In contrast, the Associate exams consist of 65 questions that must be answered in 130 minutes, averaging 2 minutes per question.

You may conclude from this that the Professional exam gives you a bit more breathing room. And you would be wrong.

I previously mentioned that the Professional questions are longer and more complex compared to the Associate questions. These factors quickly eat those ‘extra’ 24 seconds. Many candidates have noted anecdotally that the timing of the Professional exams is very tight and, having now taken one, I completely agree!

My preferred strategy is to go through the questions in order and get a quick gut feel for confidence. If the question involves services I frequently use, or if the answer is well established from my studies then I’ll answer it. If not, I flag it and move on. I’ll try to make this decision within 30 seconds.

My initial goal is to see all 75 questions with as close to 90 minutes remaining as possible. This way, when I reach the end of the questions, I know how many are unanswered and how long I have left to answer them. I can then revisit these questions using a more methodical approach, potentially drawing on other questions I have already answered.

However, this required a change to the way I recorded my progress…

Kindness Through Panic

Since my earliest certifications, I’ve used a Gut Feel system using my own notepad during mocks and the test centre’s whiteboards during exams. I create an empty table with three confidence ratings:

  • 100: I’m 100% sure of the answer.
  • 5050: I’ve narrowed it down to two answers.
  • ?: I have no idea.

As I move through the questions, each question number is recorded in one of these rows.

However, there’s nothing here for situations where I’ve speed-read the question and chosen not to answer it. The closest option was ‘?‘, but that means ‘I don’t know the answer’, whereas I wanted ‘I haven’t properly read the question‘.

Enter my latest addition: PANIC.

Panic is somewhat hard to articulate, so I’ll describe how I use it. A question will get Panic if my initial thoughts are along the lines of:

  • I’m currently panicking (I mean yeah – Ed).
  • I don’t want to try this question yet (for whatever reason).
  • I don’t feel ready to try this question yet (for whatever reason).

Or any other reason – this list isn’t exhaustive.

Professional exams are expensive, time-consuming and complex. It is completely reasonable to get adrenaline and anxiety in this situation. Panic lets me be kind to myself and build some forward momentum. I can then do second, third and fourth passes to attack the Panic queue.

It’s similar to an SQS queue visibility timeout. When a Panic question is pulled from the queue, it temporarily disappears. While it’s invisible, I can process other messages without it blocking my progress. Once I’ve completed my first pass, the timeout expires, the message reappears and I can handle it with fresher eyes and more context from the questions I’ve already answered.

At the end of an exam, I end up with something like this:

DOPPaper600

Combining this physical ledger with the exam software’s flagging feature lets me track unanswered questions and the reasons for skipping them. This gives me more mental bandwidth to actually answer the questions.

Hallucinations Aren’t Limited to AI

One of the biggest mistakes I repeatedly made during my mock exams was adding details that weren’t in the text. Who says AI is the only thing that can hallucinate?

I’ll illustrate what I mean with a paraphrased mock exam question:

A company has confidential files in an Amazon S3 bucket. Actions on objects need to be monitored, such as PUT, GET, and DELETE. The goal is to easily search for and review these actions for auditing purposes.

Four answers were provided. I narrowed it down to two options, one of which seemed wrong because it would trigger unnecessary Lambda executions.

But this answer was correct. And the reason my chosen answer would never have worked? It assumed a CloudTrail trail was already enabled on the bucket. The Lambda answer didn’t make that assumption, explicitly enabling the trail as a step. I’d hallucinated a prerequisite into existence because it’s what I’d have done instinctively in a real environment. Oops! This wasn’t the only time I caught myself out like that either.

So yes. Read the question. Then READ THE QUESTION. And then choose the answer that fits the requirements, not the one that needs some bending and stretching. And not the one that you’ve hallucinated into correctness.

Summary

Going into the AWS DevOps Engineer – Professional exam, I wasn’t sure what to expect. A harder version of the Associate exam? A different beast entirely?

As it turned out, both are true. The transition from Associate to Professional reminds me of the progress I’ve experienced in my own career. In my earlier roles, I primarily solved clearly defined problems with straightforward solutions. In my current consulting role, I concentrate on understanding context, navigating ambiguity, evaluating trade-offs and making decisions when no clear right answer exists.

While I did find the exam brutal, it does exactly what it sets out to do. I must often make important architectural and procedural decisions under time pressure and with appropriate justification, and the DevOps Pro held up a mirror to that perfectly. Would I do another? Absolutely. Although next time I might need a second whiteboard.

Like this post? Click the button below for links to contact, socials, projects and sessions:

SharkLinkButton 1

Thanks for reading ~~^~~