How it happened
Marvin Schwäbe was the busiest player on the pitch for most of this game. The Köln goalkeeper made six saves and earned a match rating of 7.2, and he kept the score level at 0-0 at half-time and well beyond it.
Frankfurt finally broke through in the 77th minute, when Y. Ebnoutalib scored the only goal of the game. Köln had no reply, and the home side held on for a 1-0 win. There were no red cards.
The numbers
Frankfurt were the better side on the numbers. They had 14 shots to Köln's nine, and seven of them were on target against three. They also won the corner count seven to three and held 56% of possession.
The expected-goals figures agree: 1.34 for Frankfurt and 0.65 for Köln, a gap of 0.69. A one-goal margin is a fair reflection of that, and Schwäbe's saves explain why it stayed so narrow for so long.
At the other end, Noah Atubolu made three saves and posted the highest match rating of the game, 8.2. His team-mate Robin Koch followed with 7.9 after 84 touches. For Köln, Borna Sosa had a match rating of 7.6, with four key passes and 97 touches, the most creative contribution on his side.
What it means
Frankfurt now sit eighth in the Bundesliga with eight points from six matches, one place and three positions better than a Köln side in 11th with seven points. The gap between them is a single point.
The head-to-head record between these clubs is almost impossible to separate: of 84 meetings, Köln have won 29, Frankfurt 27 and 28 have been drawn. This result leaves Frankfurt's tally one closer to Köln's.