Comincia a lavorare agli studi di Cinecittà come stuntman fra il 2005 e il 2007, per poi passare a piccoli ruoli in sceneggiati televisivi.
Esordisce al cinema nel 2011 con il film Cinque; ottiene poi i ruoli da co-protagonista in Roma criminale (2013, nella parte di Marco Lanzi), Suburra (2015, con il ruolo di Aureliano Adami detto "Numero 8") e Non essere cattivo (2015, presentato fuori concorso alla 72ª Mostra internazionale d'arte cinematografica di Venezia, in cui interpreta Vittorio): con quest'ultima interpretazione vince il premio Nuovo Imaie Talent Award come miglior attore italiano esordiente e viene nominato come miglior attore protagonista ai David di Donatello 2016.
Nel 2015 gli viene inoltre consegnato da Francesco Fiumarella, autore del Premio Internazionale "Vincenzo Crocitti", il riconoscimento come miglior attore e rivelazione dell'anno.
Nel 2016 appare come ospite, assieme ad Alessandro Roja, nella terza puntata di Top Gear Italia.
Nel 2017 interpreta il cantante Luigi Tenco nel film biografico Dalida, sulla vita dell'omonima cantante, e viene selezionato per rappresentare l'Italia allo Shooting Stars Award, premio per promettenti giovani attori europei assegnato nel corso della Berlinale.
Sempre nel 2017 è il padrino della 74ª Mostra internazionale d'arte cinematografica di Venezia.
Nell'ottobre 2017 è protagonista di Suburra - La serie, prodotta da Netflix e prequel dell'omonimo film del 2015, tornando ad interpretare il ruolo di Aureliano Adami; il 22 febbraio 2019 viene pubblicata sulla piattaforma streaming la seconda stagione della serie; il 30 ottobre 2020 viene pubblicata la terza ed ultima stagione.
Nel 2018 interpreta il ruolo di Stefano Cucchi in “Sulla mia pelle” di Alessio Cremonini (anch'esso una produzione Netflix) con cui vince il Premio Pasinetti speciale al film e ai migliori attori, il Premio Brian, il Premio FEDIC alla 75ª Mostra internazionale d'arte cinematografica di Venezia e il David di Donatello come miglior attore protagonista.
Nell'occasione ha dichiarato come il premio da lui ricevuto “sia di Stefano Cucchi”.
In seguito è protagonista del kolossal italiano prodotto da Rai Cinema, Il primo re, diretto da Matteo Rovere ed interpretato assieme ad Alessio Lapice, versione rivisitata del mito di Romolo e Remo, distribuito nel circuito cinematografico dal 31 gennaio 2019, e della commedia Di tutti i colori di Max Nardari, uscita in Italia il 18 giugno 2019 (dopo esser stata distribuita in Russia nel 2017 col titolo Liubov pret-a-porter).
Nel marzo del 2019 è il protagonista del videoclip di Lunedì, canzone del rapper italiano Salmo.
Nel 2020 è protagonista della co-produzione internazionale Diavoli, serie televisiva tratta dall'omonimo romanzo di Guido Maria Brera ed ambientata nel mondo dell'alta finanza londinese, co-prodotta e trasmessa da Sky Atlantic e girata in lingua inglese, in cui è affiancato da Patrick Dempsey e Kasia Smutniak.
Nella versione italiana l'attore per sua scelta ha deciso di non auto-doppiarsi (recita infatti con la voce di Andrea Mete).
Nel dicembre 2022 è il protagonista del film Sky original “The Hanging Sun – Sole di mezzanotte”, libero adattamento dell’omonimo thriller del romanziere norvegese più famoso al mondo, trasmesso da Sky Cinema.