The Effect of Alcohol on My Sleep
Light drinking has a very small effect on my sleep (obviously your mileage may vary!)
I’ve had an Oura ring for almost 2.5 years, and I’ve been tracking my alcohol consumption for almost three years. Over that time, I’ve averaged having alcohol about three days a week, meaning I have a data set of hundreds of days where I didn’t drink any alcohol, and hundreds of days where I did drink alcohol.
In other words, I have a great data set to be able to detect the effect of alcohol on my sleep!
Every morning, I fill out a form. In that form, I indicate (among many other things):
how many alcoholic beverages I had the day before (my estimate, generally rounded to the nearest 0.5)
how positive I feel that morning (1-10)
Additionally, my Oura ring collects data on my sleep. So… what effect does alcohol have?
The short answer is that the effects are not huge:
I seem to sleep a tiny bit more when I don’t have alcohol
alcohol seems to decrease my HRV
I get slightly more deep sleep when I have had alcohol
alcohol doesn’t seem to have any effect at all on REM sleep, resting heart rate, or how I feel the next morning
I was somewhat surprised by this. Several friends have told me that alcohol has a measurable and large effect on their sleep quality. Having a drink or two (I very rarely drink more than that) appears to have a limited effect on me.
I excluded nights where I was on vacation from this analysis. Being on vacation means different habits (work, exercise, food, alcohol), and it was easiest to just remove that data.
Sleeping Slightly Better and More Without Alcohol
I sleep more on Saturday and Sunday nights, and there are some other differences by day of the week.
Layering alcohol on top of the day of the week shows a consistent pattern: my Oura sleep score is about one point higher when I don’t drink alcohol than when I do. My average is 76 when I don’t have alcohol, and 75 when I do. The one exception to this is Fridays, where my sleep score is higher on nights when I have alcohol. I suspect that this is noise and will monitor it.
I also tend to sleep differently based on how much activity I had the day before: I actually have higher sleep scores when I have had less physical activity.
On average, I sleep about five minutes more on nights when I haven’t had alcohol.
The Morning After Drinking Alcohol, I Feel… the Same
I tend to feel best on weekdays (come to your own conclusion as to what that means!) and worst on Sunday mornings. There doesn’t appear to be an effect of alcohol on how positive I feel the next morning.
Note that the day listed below is the day I drank alcohol (or didn’t drink). My feeling (positive or negative) is the following morning.
There don’t seem to be significant trends as to how I feel in the morning based on my activity level the day prior.
Alcohol Doesn’t Seem to Affect My HRV
My heart rate variability — which is higher during the week — doesn’t seem to be affected by alcohol.
I Get More Deep Sleep When I Drink Alcohol
When I drink alcohol, my deep sleep percentage (according to Oura) increases from about 20% to about 21%. The trend is clear and consistent when looking at day of the week.
The trend gets a little more muddled when looking at days by activity level. It looks like I get much more deep sleep on days with high activity when I drink than on days with a lot of activity where I don’t drink. Interestingly (maybe it’s noise?) there seems to be very little effect on deep sleep when I exercise less.
More Notes
Alcohol seems to have little or no effect on REM sleep and little or no effect on my resting heart rate.
My drinking is moderate. I infrequently have more than one drink, and I very rarely have more than two drinks (eleven times in almost three years). My average number of alcoholic drinks on days when I drink is 1.1.
I leaned quite heavily on Claude to do this analysis. It took me under an hour to give Claude my Postgres schema and give it enough context to do this analysis. I did have to look closely at the queries, and had to correct it once or twice when it was struggling to line up the correct dates from my Airtable form with the data from Oura. The SQL is below.
-- First query with day of week
WITH sleep_metrics AS (
SELECT
o.bedtime_start::date as sleep_date,
CASE WHEN m.alcoholic_drinks > 0 THEN 'With Alcohol' ELSE 'No Alcohol' END as drinking_status,
m.alcoholic_drinks,
o.total_sleep_duration/3600.0 as total_hours,
o.efficiency,
o.deep_sleep_duration/o.total_sleep_duration::float * 100 as deep_sleep_pct,
o.rem_sleep_duration/o.total_sleep_duration::float * 100 as rem_sleep_pct,
o.restless_periods,
o.average_hrv,
o.lowest_heart_rate as resting_hr,
o.latency/60.0 as sleep_latency_minutes,
EXTRACT(EPOCH FROM o.bedtime_start::time)/3600 as bedtime_hour,
o.score as sleep_quality_score,
EXTRACT(DOW FROM o.bedtime_start) as day_of_week,
m.positivity
FROM oura_details o
JOIN mornings m ON o.bedtime_start::date + interval '1 day' = m.day
WHERE o.total_sleep_duration > 7200
AND m.alcoholic_drinks IS NOT NULL
AND NOT m.on_vacation_yesterday
)
SELECT
CASE day_of_week::integer
WHEN 0 THEN 'Sunday'
WHEN 1 THEN 'Monday'
WHEN 2 THEN 'Tuesday'
WHEN 3 THEN 'Wednesday'
WHEN 4 THEN 'Thursday'
WHEN 5 THEN 'Friday'
WHEN 6 THEN 'Saturday'
END as day_of_week,
drinking_status,
COUNT(*) as nights,
TRUNC(AVG(total_hours)::numeric, 2) as avg_sleep_hours,
TRUNC(AVG(efficiency)::numeric, 2) as avg_efficiency,
TRUNC(AVG(deep_sleep_pct)::numeric, 2) as deep_sleep_pct,
TRUNC(AVG(rem_sleep_pct)::numeric, 2) as rem_sleep_pct,
TRUNC(AVG(sleep_latency_minutes)::numeric, 1) as avg_latency_mins,
TRUNC(AVG(sleep_quality_score)::numeric, 1) as avg_sleep_score,
TRUNC(AVG(average_hrv)::numeric, 2) as avg_hrv,
TRUNC(AVG(resting_hr)::numeric, 1) as avg_resting_hr,
TRUNC(AVG(positivity)::numeric, 2) as avg_positivity,
CASE WHEN drinking_status = 'With Alcohol'
THEN TRUNC(AVG(alcoholic_drinks)::numeric, 2)
ELSE 0
END as avg_drinks_when_drinking,
TRUNC(STDDEV(bedtime_hour)::numeric, 2) as bedtime_consistency_hrs
FROM sleep_metrics
GROUP BY day_of_week, drinking_status
HAVING COUNT(*) > 20
ORDER BY day_of_week::integer, drinking_status;
-- Second query with activity levels
WITH exercise_metrics AS (
SELECT
o.bedtime_start::date as sleep_date,
CASE WHEN m.alcoholic_drinks > 0 THEN 'With Alcohol' ELSE 'No Alcohol' END as drinking_status,
m.alcoholic_drinks,
f.minutes_very_active,
f.minutes_fairly_active,
f.steps,
o.total_sleep_duration/3600.0 as total_hours,
o.efficiency,
o.deep_sleep_duration/o.total_sleep_duration::float * 100 as deep_sleep_pct,
o.rem_sleep_duration/o.total_sleep_duration::float * 100 as rem_sleep_pct,
o.score as sleep_quality_score,
o.average_hrv,
o.lowest_heart_rate as resting_hr,
m.positivity
FROM oura_details o
JOIN mornings m ON o.bedtime_start::date + interval '1 day' = m.day
LEFT JOIN fitbit_exercise f ON o.bedtime_start::date = f.date
WHERE o.total_sleep_duration > 7200
AND m.alcoholic_drinks IS NOT NULL
AND f.minutes_very_active IS NOT NULL
AND NOT m.on_vacation_yesterday
),
activity_levels AS (
SELECT
*,
CASE
WHEN minutes_very_active >= 75 THEN 'Very High Activity (75+ min)'
WHEN minutes_very_active >= 45 THEN 'High Activity (45-75 min)'
ELSE 'Light Activity (<45 min)'
END as activity_level
FROM exercise_metrics
)
SELECT
activity_level,
drinking_status,
COUNT(*) as nights,
TRUNC(AVG(total_hours)::numeric, 2) as avg_sleep_hours,
TRUNC(AVG(efficiency)::numeric, 2) as avg_efficiency,
TRUNC(AVG(deep_sleep_pct)::numeric, 2) as deep_sleep_pct,
TRUNC(AVG(rem_sleep_pct)::numeric, 2) as rem_sleep_pct,
TRUNC(AVG(sleep_quality_score)::numeric, 1) as avg_sleep_score,
TRUNC(AVG(average_hrv)::numeric, 2) as avg_hrv,
TRUNC(AVG(resting_hr)::numeric, 1) as avg_resting_hr,
TRUNC(AVG(positivity)::numeric, 2) as avg_positivity,
CASE WHEN drinking_status = 'With Alcohol'
THEN TRUNC(AVG(alcoholic_drinks)::numeric, 2)
ELSE 0
END as avg_drinks_when_drinking,
TRUNC(AVG(minutes_very_active)::numeric, 1) as avg_active_minutes
FROM activity_levels
GROUP BY activity_level, drinking_status
ORDER BY
CASE activity_level
WHEN 'Light Activity (<45 min)' THEN 1
WHEN 'High Activity (45-75 min)' THEN 2
WHEN 'Very High Activity (75+ min)' THEN 3
END,
drinking_status;