Specialista della terra rossa, è stato semifinalista al Roland Garros 2018, diventando il terzo italiano nell'era Open a essersi spinto così avanti in un torneo del Grande Slam. Nel 2019 è stato n. 16 del mondo, nona migliore classifica ATP raggiunta da un tennista italiano, a pari merito con Luciano Darderi. Ha conquistato tre titoli ATP su cinque finali disputate.

Carriera Inizi A sei anni prende per la prima volta in mano una racchetta. Il suo primo allenatore è il cugino Francesco Palpacelli, che in passato aveva allenato Roberta Vinci. Nel 2009 si trasferisce a Caldaro passando sotto la guida dei tecnici Massimo Sartori, Riccardo Piatti e successivamente Cristian Brandi. Sono passaggi cruciali per la definizione del suo stile di gioco e del suo modo di stare in campo. Nell'ITF Junior Circuit vince solo un torneo Grade 5 nel 2009 e all'inizio del 2010 raggiunge la 100ª posizione nella classifica mondiale juniores.

2010-2012: primi titoli ITF Nel marzo 2010 fa la sua prima apparizione tra i professionisti nelle qualificazioni del Challenger di Caltanissetta e viene subito eliminato. In giugno fa il suo debutto nel tabellone principale di un torneo del circuito ITF al Futures Italy F12 di Mestre e viene battuto da Lorenzo Giustino. Quello stesso mese vince i suoi primi incontri nelle qualificazioni del Challenger di Milano e perde l'incontro decisivo. All'Italy F16 vince i primi incontri in un tabellone principale ITF e viene eliminato nei quarti di finale, risultati che gli valgono i primi punti ATP.

Nell'aprile 2011 disputa e perde la sua prima finale tra i professionisti nel torneo di doppio all'Italy F4. A giugno raggiunge la prima semifinale in singolare in un Futures all'Italy F12 e viene sconfitto da Stefano Travaglia. A luglio alza il suo primo trofeo vincendo con Francesco Aldi il doppio all'Italy F17. Entra per la prima volta nel tabellone principale di un torneo Challenger a Orbetello e perde al primo turno. Il 18 marzo 2012 vince il primo torneo ITF in singolare al Futures Croatia F3 battendo 6–3, 6–4 Andrej Martin in finale. A maggio partecipa per la prima volta alle qualificazioni di un torneo ATP agli Internazionali d'Italia e al primo turno supera il nº 61 del mondo Gō Soeda, primo top 100 da lui sconfitto, prima di cedere a Blaž Kavčič. In luglio vince il suo primo incontro nel tabellone principale di un Challenger alla San Benedetto Tennis Cup e viene poi eliminato da Michael Lammer. A settembre disputa la prima finale Challenger in doppio agli Internazionali di Tennis dell'Umbria assieme ad Alessio Di Mauro e vengono sconfitti da Martin Fischer / Philipp Oswald.

2013: primo trofeo Challenger In febbraio perde la finale del Futures Croatia F1 e a marzo vince il Croatia F3 di Umago sconfiggendo in finale Attila Balázs. A maggio supera Evgenij Donskoj nelle qualificazioni degli Internazionali d'Italia e si arrende a Santiago Giraldo al turno decisivo. A Nizza supera per la prima volta le qualificazioni di un torneo ATP battendo Stephan Fransen, Florent Serra e Thiemo de Bakker; il 20 maggio disputa il primo incontro in un main draw ATP perdendo in tre set contro Fabio Fognini. In luglio vince il Futures Italy F17 sconfiggendo in finale Dominic Thiem. L'11 agosto vince il suo primo torneo Challenger al San Marino Open battendo in finale Filippo Volandri ed entra per la prima volta nella top 200. Dopo la finale persa al Challenger di Sibiu contro Jaroslav Pospíšil, a ottobre porta il best ranking al 161º posto.

2014: prima partecipazione agli Internazionali d'Italia

Comincia il 2014 venendo eliminato nelle qualificazioni all'ATP di Doha e agli Australian Open, alla sua prima esperienza in un torneo dello Slam. In marzo vince due tornei ITF consecutivi e raggiunge le semifinali nei Challenger di Vercelli e Roma. In maggio vince il torneo di pre-qualificazione agli Internazionali d'Italia e con una wild card debutta nel main draw di un torneo Masters 1000, dove viene eliminato al primo turno da Igor Sijsling. Per la prima volta tenta le qualificazioni al Roland Garros ed esce di scena al secondo turno.

In giugno perde la finale al Challenger di Mestre contro Pablo Cuevas. Dopo la semifinale raggiunta al successivo Challenger di Milano sale al 134º posto del ranking. Nel torneo ATP di Stoccarda supera le qualificazioni e perde al primo turno contro Guillermo García López, mentre non supera le qualificazioni ad Amburgo. A Umago supera il tabellone cadetto e nel primo turno del main draw viene sconfitto da Andreas Seppi. Eliminato nelle qualificazioni agli US Open, a fine stagione vince a Biella il primo titolo Challenger in doppio, in coppia con Matteo Viola sconfigge in finale Frank Moser / Alexander Satschko; nel torneo di singolare perde in semifinale contro Filippo Volandri. Chiude il 2014 alla posizione nº 159 del ranking.

2015: secondo titolo Challenger e top 100 Eliminato nelle qualificazioni a Doha, agli Australian Open e a San Paolo, entra nel tabellone principale e viene eliminato al primo turno a Rio de Janeiro e Buenos Aires. Al suo esordio nelle qualificazioni dei Masters 1000 primaverili negli Stati Uniti viene subito eliminato sia a Indian Wells che a Miami. Dopo le semifinali raggiunte nei Challenger di Napoli e Vercelli, il 3 maggio 2015 si aggiudica il Challenger di Torino battendo in finale in due set Kimmer Coppejans. Esce nelle qualificazioni agli Internazionali d'Italia e al Roland Garros. Nei due mesi successivi raggiunge 5 semifinali Challenger e a luglio fa il suo ingresso nella top 100. Non supera le qualificazioni ad Amburgo e nel Masters 1000 di Cincinnati. Fa il suo esordio assoluto in un torneo del Grande Slam agli US Open e viene sconfitto da Mardy Fish. Il mese successivo perde la finale al Genoa Open Challenger contro Nicolás Almagro e a ottobre porta il best ranking all'82ª posizione. Si qualifica per le ATP Challenger Tour Finals di San Paolo e viene eliminato nel round-robin con le sconfitte contro Guilherme Clezar e Radu Albot.

2016: terzo titolo Challenger L'ascesa nel ranking gli garantisce l'accesso diretto al tabellone principale di alcuni tornei ATP ed esce al primo turno a Doha, agli Australian Open, a Rio de Janeiro e a Buenos Aires. A marzo fa il suo esordio nella squadra italiana di Coppa Davis in occasione della vittoriosa sfida di Gruppo Mondiale contro la Svizzera, viene schierato a risultato acquisito e supera Adrien Bossel per 6–3, 7–5. A Bucarest vince il primo incontro in un torneo ATP sconfiggendo 6-2, 6–4 al primo turno Marcos Baghdatis. Supera poi Damir Džumhur e nei quarti viene eliminato da Federico Delbonis. Esce al primo turno nei Masters 1000 di Monte Carlo e Roma, nei quali era entrato in tabellone con una wild card, e al Roland Garros.

A giugno conquista a Milano il suo terzo Challenger in singolare superando in finale Laslo Đere con un duplice 6–2. In luglio viene squalificato per 18 mesi dal Tribunale Federale della FIT e condannato a un'ammenda di 40.000 euro per aver perso volontariamente contro il n° 338 ATP Kamil Majchrzak l'8 ottobre 2015 al Challenger di Mohammedia. Fa ricorso contro la squalifica e prosegue l'attività perdendo la finale al Challenger di Como e viene eliminato nelle qualificazioni all'ATP di Stoccolma. Il 29 ottobre la sentenza d'appello riduce la squalifica a 12 mesi e la sanzione pecuniaria a 20.000 euro. In dicembre viene estinto il procedimento disciplinare a suo carico per il ritardo con cui CONI e FIT avevano presentato la richiesta di squalifica. A fine stagione sceglie come nuova guida tecnica Simone Vagnozzi.

2017: un titolo Challenger in singolare e due in doppio Sconfitto nelle qualificazioni ai primi tornei ATP stagionali, le supera a Rio de Janeiro ed esce di scena al primo turno. Perde all'esordio anche a San Paolo e a marzo conquista il Futures Italy F5, mentre al Challenger di Barletta vince il doppio in coppia con Matteo Donati. A maggio perde la finale del Challenger di Ostrava contro Stefano Travaglia e vince il Challenger di Roma superando in finale Jozef Kovalík. Eliminato al turno decisivo delle qualificazioni del Roland Garros, perde la finale nel Challenger di Todi e dopo oltre un anno torna nella top 100 del ranking. La nuova classifica gli garantisce per la prima volta l'accesso al tabellone principale di Wimbledon, e raccoglie solo 4 giochi al primo turno contro Kei Nishikori.

Battendo Gilles Simon raggiunge il secondo turno del 250 di Umago e viene sconfitto da Ivan Dodig. Esce quindi al primo turno ad Amburgo e nelle qualificazioni agli US Open. Perde nuovamente la finale al Challenger di Como, stavolta contro Pedro Sousa, e subito dopo conquista il titolo di doppio al Sibiu Open in coppia con Matteo Donati, superando in finale Sander Gillé / Joran Vliegen. Chiude l'anno al 109º posto mondiale.

2018: due titoli ATP, semifinale al Roland Garros e top 20 Il primo risultato di rilievo del 2018 è il titolo vinto a marzo al Santiago Challenger battendo in finale Gomez-Herrera, e raggiunge poi le semifinale a Marbella e ad Alicante. Supera le qualificazioni a Monte Carlo, vince il suo primo incontro nel tabellone principale di un Masters 1000 superando Damir Džumhur e viene poi sconfitto da Milos Raonic. Il 29 aprile vince il primo torneo del circuito maggiore a Budapest, ripescato come lucky loser, elimina nell'ordine Mirza Bašić, Damir Dzumhur, Jan-Lennard Struff e in semifinale Andreas Seppi, in finale batte 7–5 6–4 John Millman e sale al 59º posto della classifica mondiale. Allunga la striscia positiva a Monaco, dove al debutto supera Fabio Fognini, primo top 20 battuto in carriera, e al secondo turno perde contro Márton Fucsovics. Agli Internazionali d'Italia gioca con una wild card e batte Pablo Cuevas prima di cedere al secondo turno in tre set al nº 10 ATP David Goffin.

Al turno d'esordio del Roland Garros vince il suo primo incontro in uno Slam battendo 10–8 al quinto set Marius Copil, elimina quindi Marco Trungelliti e la testa di serie nº 10 Pablo Carreño Busta con lo score di 2–6, 7–6, 6–3, 6–1. Negli ottavi si impone per 7–5, 4–6, 6–0, 6–3 sul nº 9 del mondo David Goffin, primo top 10 sconfitto in carriera. Nel quarti batte 6–3, 7–6, 1–6, 7–6 Novak Đoković, ex nº 1 del mondo e campione a Parigi nel 2016, diventando il terzo italiano a raggiungere la semifinale di un Major nell'era Open. In semifinale si arrende in tre set a Dominic Thiem ma le imprese di Parigi gli valgono la 27ª posizione nella classifica mondiale.

Fa il suo debutto sull'erba a Eastbourne e battendo Denis Istomin ottiene la prima vittoria sull'erba nel circuito ATP. Nei quarti sconfigge John Millman per poi cedere in semifinale a Lukáš Lacko. A Wimbledon è testa di serie nº 29 e viene eliminato al primo turno da Alex de Minaur. Il 22 luglio vince a Umago il secondo titolo ATP; supera a fatica Jiří Veselý e vince nettamente nei quarti contro Laslo Đere e in semifinale contro Trungelliti, e in finale ha la meglio su Guido Pella per 6–2, 7–6. Nel ranking mondiale sale alla posizione nº 22. La settimana successiva esce al primo turno ad Amburgo.

Eliminato al primo turno nei tornei americani sul cemento, tra cui gli US Open, al torneo di San Pietroburgo vince il primo incontro ATP sul cemento battendo Lukáš Lacko e cede nei quarti a Roberto Bautista Agut. A Pechino batte Marcos Baghdatis e negli ottavi Márton Fucsovics gli concede soltanto sei giochi. A Shanghai vince i suoi primi incontri sul duro in un Masters 1000 superando in rimonta Gilles Simon, dopo aver salvato un match-point, e Chung Hyeon. Al terzo turno ritrova Đoković, futuro vincitore del torneo, che si impone col punteggio di 6–4, 6–0. Il 15 ottobre fissa il suo best ranking alla 19ª posizione. Esce al primo turno negli ultimi tornei stagionali di Mosca, dove è per la prima volta testa di serie nº 1 in un torneo ATP, Basilea e al Masters 1000 di Parigi Bercy.

2019: terzo titolo ATP, 16º in classifica e discesa