Po ujrzeniu armii przeciwnika Rzymianie zaczęli się ustawiać. Na początku ustawieni byli tzw. żołnierze pierwszych szeregów (zwani antepilani), za nimi znajdowali się oszczepnicy (hastati) a dalej dowódcy oddziałów (ordinum primi). Na lewej flance znalazła się konnica ciężkozbrojna wymieszana z piechotą oraz harcownikami[17]. Ammian Marcellinus mówi, że Rzymianie prawą flankę „podstępnie ulokowali w miejscu zasłoniętym i niewidocznym”[18]. Żołnierzy germańskich było 35 tysięcy[19]. Lewą stroną, gdzie spodziewano się najbardziej zaciekłej walki, dowodził Chnodomar, po prawej zaś młody Serapion[20]. Lewą flanką Rzymu dowodził Sewerus, który ruszył jako pierwszy[21]. Zatrzymał się jednak w okolicy rowów, w których byli ukryci Germanie. Cezar ujrzawszy to, otoczony dwusetką jeźdźców dał sygnał piechocie, by ruszyła. Jednocześnie wygłaszał przemowy do swoich żołnierzy, czym zagrzewał ich do walki[22]. Rzymska armia ustawiła się naprzeciw germańskiej. W tym czasie, według relacji Ammiana, żołnierze germańscy domagali się, by książęta zsiedli z koni i walczyli razem z nimi. Pewny siebie Chnodomar rzekomo zsiadł z konia, a za nim reszta książąt[23].

Na samym początku bitwy miotano oszczepy. Niewiele potem Germanie ruszyli na jazdę rzymską[24]. Lewa flanka rzymian radziła sobie bardzo dobrze i skutecznie odpierała ataki. Natomiast prawa strona, gdzie znajdowała się jazda ciężkozbrojna zaczęła się wycofywać, gdyż zraniono ich dowódcę. Zatrzymała ich piechota rzymska, po czym ruszyli dalej w bój. Cezar widząc to zganił swoich żołnierzy [25]. Po rozbiciu i rozproszeniu jazdy rzymskiej Germanie zaatakowali piechotę. Trafili na Brakchiatów i Kornutów, którzy byli już doświadczonymi żołnierzami. Napór Germanów zmusił niejako Rzymian do utworzenia formacji żółwia (testudo). Na szczęście Rzymianom na pomoc ruszył oddział Batawów[26].
Alamanom udało się dotrzeć aż do Pierwszego Legionu (Primanorum legio), dzięki atakowi przypuszczonemu przez germańskich arystokratów. Oddziały rzymskie wówczas były ustawione w obóz pretorski, formację, w której żołnierze są ustawieni gęsto w szeregach i „stoją mocno i twardo niby wieże obronne”[27]. Rzymianom udało się odeprzeć atak, a Germanie rzucili się do ucieczki.
Uciekających goniły oddziały rzymskie. Walka była tak zacięta, że aż tępiła się broń, toteż Rzymianie w razie potrzeby dobywali oręż wroga i dalej ścigali. Alamanowie dotarli aż do Renu, który był oddalony od miejsca bitwy o 7-8 km. Nie wszystkim udało się przeprawić przez rzekę, zwłaszcza ranieni, nie umiejący pływać. Niektórym udało się przeprawić przez Ren o własnych siłach, część żołnierzy wspierała się na kompanach, a inni wspomagali się tarczami[28]. Julian zabronił żołnierzom przeprawiać się przez Ren, toteż został im jedynie ostrzał z brzegu. W międzyczasie król Chnodomar próbował uciec do Renu, gdzie miał przygotowaną łódź. Rozpoznano go jednak i pojmano razem z trzema przyjaciółmi oraz dwustoma żołnierzami[29].
Po skończonej bitwie Rzymianie rozbili nad Renem obóz, tworząc linię obronną z tarcz. Jednocześnie Ammian Marcellin podaje nam, że po stronie Rzymian zginęło 243 żołnierzy oraz czterech dowódców – trzech trybunów: Bainobaudes, Laipson oraz jeden trybun bez przydziału nieznany z imienia (tribunus vacans). Po stronie germańskiej na polu bitwy poległo aż 6000 żołnierzy[30]. O rannych zarówno z jednej jak i z drugiej strony Ammian nie mówi nic, podaje tylko, że część żołnierzy nie wliczonych w straty germańskie, zabrała rzeka. Po bitwie żołnierze mieli ogłosić Juliana augustem, ale ten zganił ich i niejako odmówił tej godności. Trafia do niego również Chnodomar, który prosił Juliana o łaskę. Ten odparł mu, żeby jest dobrej myśli. Kilka dni później Chnodomara odesłano do Mediolanu na dwór cesarski a stamtąd na wzgórze Celius (znajdował się tam obóz dla cudzoziemców), gdzie zmarł jako starzec[31].