[]
0) { let rootNavigationList = fragmentElement.querySelector(‘.ecl-inpage-navigation__list’); let sampleSubNavigationList = fragmentElement.querySelector(‘#sample-sub-inpage-navigation-list’); sampleSubNavigationList.classList.add(‘hide’); let sampleNavigationItem = fragmentElement.querySelector(‘.ecl-inpage-navigation__item’); sampleNavigationItem.classList.add(‘hide’); let skipButtonHref = ”; let currentLevel = 0; let currentNavigationList = rootNavigationList; let lastNavigationItem = null; let newNavigationItem = null; for (let i = 0; i { element.classList.remove(‘has-active-item’); }); } function updateCompactedItems(event) { const activeNavItem = document.querySelector(‘.ecl-inpage-navigation__item–active’); if (activeNavItem !== null) { let parentNavItem = activeNavItem; if (activeNavItem.parentElement.classList.contains(‘estat-inpage-navigation–compact’)) { parentNavItem = activeNavItem.parentElement.parentElement; } if (!parentNavItem.classList.contains(‘has-active-item’)) { clearActivatedParents(); parentNavItem.classList.add(‘has-active-item’); } } else { clearActivatedParents(); } } function navItemObserverCallback(mutationList, observer) { mutationList.forEach(function(mutation) { if (mutation.type === ‘attributes’ && mutation.attributeName === ‘class’) { updateCompactedItems(); } }); } function navItemObserverInit() { const options = {attributes: true}; const navItemObserver = new MutationObserver(navItemObserverCallback); const navItems = document.querySelectorAll(‘.ecl-inpage-navigation__item’); navItems.forEach((navItem) => { navItemObserver.observe(navItem, options); }); } $(document).ready(function() { const notInEditMode = document.querySelector(‘.fragments-editor’) == null; if (notInEditMode) { inpageNavigationFragmentInit(); const isHasSelectorSupported = CSS.supports(‘selector(:has(*))’); if (!isHasSelectorSupported && document.querySelector(‘nav.in-compact-mode’) !== null) { console.log(‘has() selector is not supported -> navigation in compact mode is handled by auxiliary scripts’); navItemObserverInit(); }; ECL.autoInit(); } else { const sampleNavigationItem = fragmentElement.querySelector(‘.ecl-inpage-navigation__item’); sampleNavigationItem.classList.remove(‘hide’); }; });;}());]]>
Printing can have negative environmental impacts due to paper waste. We encourage you to explore eco-friendly alternatives. Bookmarking this page in your browser allows you to access it anytime.
This publication can also be converted to PDF, if you have a PDF printer installed on your computer. PDF printers function as virtual printers, enabling you to create digital copies of web pages and access the content offline.
{ const buttonPrintPage = document.getElementById(‘estat-print-page-modal-toggle’); const cookieSkipModal = ‘skipModalBeforePrinting’; if (configuration.displayInPageHeader) { const headerElement = document.querySelector(‘.ecl-page-header .ecl-page-header__meta’) || document.querySelector(‘.ecl-page-header .ecl-page-header__title-container ‘) if (headerElement) { headerElement.prepend(buttonPrintPage); headerElement.classList.add(‘ecl-u-width-100’) } } buttonPrintPage.addEventListener(‘click’, () => { const skipModal = readCookie(cookieSkipModal); if (skipModal == ‘true’) { window.print(); } else { const eclModalElement = document.getElementById(‘estat-print-page-modal’); const eclModal = ECL.components.get(eclModalElement); eclModal.openModal(); } }); document.getElementById(‘print-submit’).addEventListener(‘click’, () => { const skipModal = document.getElementById(‘checkbox-skip-modal’).checked if (skipModal) { writeCookieWithMaxAgeValue(cookieSkipModal, ‘true’, 15768000); } else { deleteCookie(cookieSkipModal); } window.print(); }); });;}());]]>
In the EU, GDP up by 0.4% and employment up by 0.2%
GDP growth in the euro area and the EU
In the fourth quarter of 2024, seasonally adjusted GDP increased by 0.2% in the euro area and by 0.4% the EU, compared with the previous quarter, according to an estimate published by Eurostat, the statistical office of the European Union. In the third quarter of 2024, GDP had grown by 0.4% in both areas.
For the year 2024 as a whole, GDP increased by 0.9% in the euro area and by 1.0 in the EU, after +0.4% in both zones in 2023.
Compared with the same quarter of the previous year, seasonally adjusted GDP increased by 1.2% in the euro area and by 1.4% in the EU in the fourth quarter of 2024, after +1.0% in the euro area and +1.1% in the EU in the previous quarter.
During the fourth quarter of 2024, GDP in the United States increased by 0.6% compared to the previous quarter (after +0.8% in the third quarter of 2024). Compared with the same quarter of the previous year, GDP increased by 2.5% (after +2.7% in the previous quarter).
GDP growth by Member State
Ireland (+3.6%) recorded the highest increase of GDP compared to the previous quarter, followed by Denmark (+1.6%) and Portugal (+1.5%). The highest decreases were observed in Malta (-0.7%), Austria (-0.4%), Germany and Finland (both -0.2%).
GDP components and contributions to growth
GDP components evolved in the fourth quarter of 2024 as follows:
-
government final consumption expenditure increased by 0.4% in the euro area and by 0.3% the EU (after +0.9% in both areas in the previous quarter),
-
gross fixed capital formation increased by 0.6% in the euro area and by 0.5% the EU (after +1.8% and +1.5% respectively),
The contribution to GDP growth from:
-
government final expenditure was positive for both the euro area and the EU (+0.1 pp for both),
-
gross fixed capital formation was positive for both the euro area and the EU (+0.1 pp for both),
-
changes in inventories was negative for both the euro area and the EU (-0.2 pp for both), and
-
exports less imports was negligible for both the euro area and the EU.
Employment growth in the euro area and EU
The number of employed persons increased by 0.1% in the euro area and by 0.2% in the EU in the fourth quarter of 2024, compared with the previous quarter. In the third quarter of 2024, employment had increased by 0.2% in the euro area and had remained stable in the EU.
For the year 2024 as a whole, the number of persons employed increased by 1.0% in the euro area and by 0.8% in the EU, after +1.4% and +1.2% respectively in 2023.
Compared with the same quarter of the previous year, employment increased by 0.7% in the euro area and by 0.5% in the EU in the fourth quarter of 2024, after +1.0% in the euro area and +0.8% in the EU in the third quarter of 2024.
Hours worked increased by 0.6% in the euro area and by 0.5% in the EU in the fourth quarter of 2024, compared with the previous quarter. Compared with the same quarter of the previous year, the hours worked increased by 1.6% in the euro area and by 1.0% in the EU.
For the year 2024 as a whole, the number of hours worked increased by 1.0% in the euro area and by 0.7% in the EU, after +1.3% and +1.0% respectively in 2023.
These data provide a picture of labour input consistent with the output and income measure of national accounts.
Employment growth in Member States
In the fourth quarter of 2024, Romania (+2.0%), Spain (+0.9%), Greece and Portugal (both +0.5%) recorded the highest growth of employment in persons compared with the previous quarter. The highest decrease of employment was recorded in Croatia, Finland (both -0.4%), Latvia and Sweden (both -0.2%).
Employment levels in the euro area and EU
Based on seasonally adjusted figures, Eurostat estimates that in the fourth quarter of 2024, 219.7 million people were employed in the EU, of which 171.2 million were in the euro area.
Evolution of labour productivity in the euro area and EU
The combination of GDP and employment data allows an estimation of labour productivity.
In the fourth quarter of 2024, productivity based on persons increased by 0.4% in the euro area and by 0.8% in the EU compared to the same quarter of the previous year.
Based on hours worked, productivity compared with the same quarter of the previous year increased by 0.1% in the euro area and by 0.8% in the EU.
Tables
Growth rates of GDP in volume (based on seasonally adjusted* data) |
||||||||
---|---|---|---|---|---|---|---|---|
Percentage change compared with the previous quarter |
Percentage change compared with the same quarter of the previous year |
|||||||
2024Q1 |
2024Q2 |
2024Q3 |
2024Q4 |
2024Q1 |
2024Q2 |
2024Q3 |
2024Q4 |
|
0.3 |
0.2 |
0.4 |
0.2 |
0.5 |
0.5 |
1.0 |
1.2 |
|
0.3 |
0.3 |
0.4 |
0.4 |
0.6 |
0.8 |
1.1 |
1.4 |
|
0.3 |
0.3 |
0.3 |
0.2 |
0.8 |
0.9 |
1.2 |
1.1 |
|
0.8 |
0.8 |
0.8 |
0.9 |
2.0 |
2.4 |
2.8 |
3.4 |
|
0.3 |
0.3 |
0.6 |
0.7 |
0.3 |
0.5 |
1.4 |
1.8 |
|
-0.2 |
1.4 |
1.3 |
1.6 |
2.4 |
4.0 |
3.8 |
4.1 |
|
0.2 |
-0.3 |
0.1 |
-0.2 |
-0.1 |
-0.2 |
-0.3 |
-0.2 |
|
0.0 |
0.2 |
0.2 |
0.7 |
-1.0 |
-0.7 |
-0.2 |
1.1 |
|
1.6 |
-0.4 |
4.1 |
3.6 |
-3.8 |
-3.1 |
3.0 |
9.2 |
|
0.1 |
1.2 |
0.4 |
0.9 |
2.1 |
2.1 |
2.3 |
2.6 |
|
1.0 |
0.8 |
0.8 |
0.8 |
2.7 |
3.3 |
3.5 |
3.5 |
|
0.1 |
0.3 |
0.4 |
-0.1 |
1.4 |
1.0 |
1.2 |
0.6 |
|
0.6 |
1.2 |
0.4 |
1.4 |
4.3 |
3.2 |
4.2 |
3.6 |
|
0.3 |
0.1 |
0.0 |
0.1 |
0.3 |
0.6 |
0.6 |
0.6 |
|
1.7 |
0.0 |
0.9 |
0.3 |
3.8 |
3.4 |
3.6 |
2.9 |
|
-0.2 |
0.0 |
-0.2 |
0.0 |
-0.3 |
0.0 |
-0.9 |
-0.4 |
|
1.3 |
0.4 |
1.1 |
0.8 |
2.8 |
1.6 |
2.6 |
3.7 |
|
0.3 |
0.6 |
0.2 |
: |
-0.7 |
-0.1 |
1.2 |
: |
|
0.5 |
-0.2 |
-0.6 |
0.5 |
1.6 |
1.2 |
-0.7 |
0.1 |
|
1.3 |
2.8 |
-0.6 |
-0.7 |
8.4 |
8.0 |
5.0 |
2.8 |
|
-0.3 |
1.1 |
0.8 |
0.4 |
-0.6 |
0.8 |
1.7 |
1.8 |
|
-0.1 |
-0.4 |
-0.3 |
-0.4 |
-1.8 |
-1.8 |
-1.3 |
-1.2 |
|
0.8 |
1.4 |
0.1 |
1.3 |
1.7 |
3.8 |
2.0 |
3.7 |
|
0.6 |
0.4 |
0.2 |
1.5 |
1.4 |
1.5 |
1.9 |
2.8 |
|
-0.3 |
0.1 |
0.1 |
0.8 |
2.0 |
0.8 |
-0.1 |
0.7 |
|
0.0 |
0.1 |
0.4 |
0.6 |
2.0 |
0.9 |
1.3 |
1.1 |
|
0.7 |
0.3 |
0.3 |
0.5 |
2.7 |
2.0 |
1.7 |
1.7 |
|
0.4 |
0.2 |
0.5 |
-0.2 |
-1.6 |
-1.2 |
0.9 |
1.2 |
|
0.7 |
0.2 |
0.6 |
0.8 |
0.1 |
0.4 |
0.9 |
2.4 |
|
1.7 |
1.7 |
-2.8 |
1.5 |
0.8 |
-0.1 |
-0.5 |
2.1 |
|
0.3 |
1.8 |
-1.6 |
-0.6 |
1.3 |
4.1 |
3.2 |
-0.2 |
|
0.4 |
0.5 |
0.4 |
0.2 |
0.6 |
1.3 |
1.6 |
1.6 |
|
0.4 |
0.7 |
0.8 |
0.6 |
2.9 |
3.0 |
2.7 |
2.5 |
Growth rates of employment in persons* |
||||||||
---|---|---|---|---|---|---|---|---|
Percentage change compared with the previous quarter |
Percentage change compared with the same quarter of the previous year |
|||||||
2024Q1 |
2024Q2 |
2024Q3 |
2024Q4 |
2024Q1 |
2024Q2 |
2024Q3 |
2024Q4 |
|
0.3 |
0.1 |
0.2 |
0.1 |
1.1 |
0.9 |
1.0 |
0.7 |
|
0.3 |
0.1 |
0.0 |
0.2 |
1.0 |
0.9 |
0.8 |
0.5 |
|
0.1 |
0.0 |
0.0 |
0.1 |
0.4 |
0.2 |
0.2 |
0.2 |
|
0.2 |
0.4 |
0.1 |
0.3 |
0.7 |
1.7 |
0.9 |
1.0 |
|
-0.2 |
0.5 |
0.0 |
-0.1 |
0.3 |
0.2 |
0.4 |
0.3 |
|
0.4 |
0.1 |
0.1 |
0.4 |
0.9 |
0.9 |
0.7 |
0.9 |
|
0.1 |
0.0 |
-0.1 |
0.0 |
0.4 |
0.2 |
0.1 |
0.0 |
|
0.6 |
0.7 |
-1.2 |
0.1 |
-1.3 |
1.2 |
0.7 |
0.2 |
|
0.1 |
1.4 |
0.8 |
0.3 |
1.9 |
2.7 |
3.6 |
2.5 |
|
0.9 |
0.0 |
0.1 |
0.5 |
1.5 |
1.0 |
1.1 |
1.4 |
|
0.4 |
0.0 |
0.7 |
0.9 |
2.9 |
1.8 |
1.9 |
2.3 |
|
0.2 |
0.1 |
0.1 |
0.0 |
0.7 |
0.6 |
0.5 |
0.4 |
|
2.5 |
1.2 |
1.0 |
-0.4 |
6.7 |
6.5 |
6.9 |
4.2 |
|
0.4 |
0.1 |
0.6 |
-0.1 |
1.5 |
1.7 |
2.3 |
1.0 |
|
0.8 |
0.4 |
0.5 |
0.3 |
2.2 |
2.1 |
2.2 |
1.7 |
|
-0.1 |
-0.1 |
-0.6 |
-0.2 |
-0.8 |
-0.7 |
-1.2 |
-1.0 |
|
-0.4 |
1.4 |
0.6 |
0.4 |
2.6 |
1.9 |
0.8 |
1.7 |
|
0.3 |
0.2 |
0.3 |
0.4 |
1.3 |
1.1 |
1.1 |
1.1 |
|
0.2 |
0.0 |
0.0 |
0.2 |
0.4 |
0.3 |
0.1 |
0.3 |
|
1.2 |
0.7 |
1.4 |
0.4 |
5.8 |
5.7 |
5.3 |
3.8 |
|
0.3 |
0.1 |
0.1 |
0.3 |
1.2 |
1.1 |
0.9 |
0.7 |
|
-0.1 |
0.0 |
0.1 |
0.0 |
0.2 |
0.0 |
0.0 |
0.0 |
|
-0.5 |
-0.2 |
0.0 |
0.2 |
-1.2 |
-0.6 |
-0.3 |
-0.8 |
|
0.5 |
0.2 |
0.5 |
0.5 |
1.6 |
1.4 |
1.7 |
1.7 |
|
2.1 |
-0.7 |
-3.1 |
2.0 |
4.0 |
3.7 |
-0.2 |
0.0 |
|
-0.1 |
-0.1 |
-0.1 |
-0.1 |
0.6 |
0.3 |
0.0 |
-0.3 |
|
-0.2 |
0.0 |
0.0 |
0.0 |
-0.1 |
-0.3 |
-0.1 |
-0.2 |
|
0.1 |
-0.3 |
0.2 |
-0.4 |
-0.1 |
-1.3 |
-0.1 |
-0.8 |
|
-0.1 |
-0.1 |
-0.1 |
-0.2 |
0.0 |
-0.2 |
-0.4 |
-0.6 |
|
0.6 |
0.4 |
: |
: |
2.7 |
2.3 |
: |
: |
|
0.3 |
0.0 |
0.1 |
0.2 |
0.7 |
0.5 |
0.5 |
0.6 |
|
0.2 |
0.1 |
0.0 |
0.3 |
1.1 |
0.5 |
0.7 |
0.6 |
Growth rates of employment in hours worked* |
||||||||
---|---|---|---|---|---|---|---|---|
Percentage change compared with the previous quarter |
Percentage change compared with the same quarter of the previous year |
|||||||
2024Q1 |
2024Q2 |
2024Q3 |
2024Q4 |
2024Q1 |
2024Q2 |
2024Q3 |
2024Q4 |
|
0.2 |
0.1 |
0.1 |
0.6 |
0.2 |
1.4 |
0.9 |
1.6 |
|
0.2 |
0.0 |
-0.1 |
0.5 |
-0.1 |
1.2 |
0.6 |
1.0 |
|
0.0 |
0.0 |
0.0 |
: |
0.4 |
0.4 |
-0.1 |
: |
|
-0.4 |
-0.2 |
-0.4 |
-0.2 |
-2.3 |
-0.4 |
-0.7 |
-0.7 |
|
-1.4 |
0.4 |
1.4 |
0.0 |
-3.0 |
-0.3 |
3.3 |
0.8 |
|
0.8 |
-0.7 |
0.1 |
0.4 |
1.5 |
0.5 |
0.1 |
0.6 |
|
-0.2 |
0.2 |
0.3 |
0.6 |
-1.2 |
-0.2 |
0.3 |
0.7 |
|
0.7 |
1.5 |
-1.7 |
-0.4 |
-3.0 |
3.1 |
2.3 |
0.0 |
|
1.3 |
0.4 |
1.8 |
0.2 |
-0.1 |
2.2 |
2.6 |
3.7 |
|
1.3 |
-0.8 |
-1.0 |
1.5 |
1.5 |
1.6 |
2.0 |
0.9 |
|
-0.4 |
1.0 |
0.4 |
1.8 |
-0.1 |
3.4 |
0.8 |
3.5 |
|
0.1 |
0.1 |
0.1 |
-0.2 |
1.1 |
1.0 |
0.8 |
0.8 |
|
1.2 |
1.9 |
-0.1 |
0.3 |
5.2 |
7.9 |
4.4 |
3.0 |
|
0.7 |
-0.5 |
0.2 |
0.2 |
2.2 |
2.5 |
2.0 |
1.6 |
|
0.4 |
-0.1 |
1.5 |
0.7 |
2.6 |
2.3 |
2.6 |
2.1 |
|
-0.5 |
-0.3 |
-1.6 |
1.9 |
-0.3 |
0.5 |
-0.5 |
-0.6 |
|
1.2 |
0.8 |
0.6 |
2.0 |
3.4 |
1.5 |
2.2 |
4.7 |
|
2.1 |
-1.2 |
0.8 |
: |
-0.8 |
1.8 |
1.7 |
: |
|
0.8 |
0.2 |
-0.4 |
0.5 |
-1.9 |
1.6 |
-0.2 |
1.9 |
|
-0.2 |
2.6 |
4.1 |
-1.0 |
-1.3 |
1.5 |
8.5 |
5.6 |
|
0.2 |
0.4 |
0.0 |
0.0 |
-0.1 |
2.1 |
1.2 |
1.5 |
|
0.2 |
-0.2 |
-1.5 |
3.0 |
-2.2 |
-1.2 |
-3.2 |
2.6 |
|
-0.6 |
-0.7 |
-0.4 |
-0.5 |
-2.3 |
-1.5 |
-1.5 |
-2.4 |
|
0.0 |
0.3 |
-0.3 |
1.9 |
-2.0 |
-0.1 |
0.2 |
4.0 |
|
2.3 |
-0.8 |
-3.3 |
1.9 |
4.2 |
4.0 |
-0.1 |
0.1 |
|
0.3 |
0.2 |
0.5 |
-0.1 |
-1.5 |
0.5 |
4.3 |
1.0 |
|
-0.3 |
-0.7 |
0.4 |
0.5 |
-1.6 |
-0.1 |
1.5 |
0.5 |
|
1.9 |
-0.7 |
-0.1 |
0.0 |
-2.8 |
1.0 |
1.7 |
1.0 |
|
0.0 |
-0.5 |
-0.4 |
0.5 |
-1.6 |
1.4 |
0.6 |
-1.5 |
|
-2.2 |
6.1 |
: |
: |
-1.0 |
4.7 |
: |
: |
|
0.1 |
-0.4 |
0.1 |
0.1 |
-3.9 |
4.8 |
1.0 |
-0.5 |
Overview on the evolution of main expenditure components
GDP and expenditure components seasonally adjusted, chain-linked volumes |
|||||
---|---|---|---|---|---|
Percentage change compared with the previous quarter |
Percentage change compared with the same quarter of the previous year |
||||
Euro area |
EU |
Euro area |
EU |
||
0.3 |
0.3 |
0.5 |
0.6 |
||
0.2 |
0.3 |
0.5 |
0.8 |
||
0.4 |
0.4 |
1.0 |
1.1 |
||
0.2 |
0.4 |
1.2 |
1.4 |
||
0.5 |
0.5 |
1.0 |
1.3 |
||
0.0 |
0.1 |
0.6 |
0.9 |
||
0.6 |
0.5 |
1.1 |
1.3 |
||
0.4 |
0.6 |
1.5 |
1.7 |
||
0.3 |
0.4 |
2.2 |
2.2 |
||
1.1 |
1.1 |
3.0 |
2.9 |
||
0.9 |
0.9 |
3.1 |
3.1 |
||
0.4 |
0.3 |
2.8 |
2.7 |
||
-2.0 |
-1.9 |
-1.0 |
-0.7 |
||
-2.5 |
-2.2 |
-3.2 |
-3.0 |
||
1.8 |
1.5 |
-1.6 |
-1.7 |
||
0.6 |
0.5 |
-2.1 |
-2.2 |
||
1.1 |
0.8 |
-0.6 |
-0.2 |
||
1.5 |
1.4 |
1.9 |
2.0 |
||
-1.4 |
-1.1 |
1.5 |
1.4 |
||
-0.1 |
0.1 |
1.1 |
1.1 |
||
-0.2 |
-0.1 |
-1.6 |
-1.2 |
||
1.0 |
1.0 |
-0.5 |
0.0 |
||
0.5 |
0.5 |
1.6 |
1.7 |
||
-0.1 |
-0.1 |
1.2 |
1.4 |
Contribution of expenditure components to change of GDP seasonally adjusted, chain-linked volumes |
||||
---|---|---|---|---|
Contribution in percentage points to GDP change compared with the previous quarter |
Contribution in percentage points to GDP change compared with the same quarter of the previous year |
|||
Euro area |
EU |
Euro area |
EU |
|
0.3 |
0.3 |
0.5 |
0.7 |
|
0.0 |
0.1 |
0.3 |
0.5 |
|
0.3 |
0.3 |
0.6 |
0.7 |
|
0.2 |
0.3 |
0.8 |
0.9 |
|
0.1 |
0.1 |
0.5 |
0.5 |
|
0.2 |
0.2 |
0.6 |
0.6 |
|
0.2 |
0.2 |
0.7 |
0.7 |
|
0.1 |
0.1 |
0.6 |
0.6 |
|
-0.4 |
-0.4 |
-0.2 |
-0.2 |
|
-0.5 |
-0.5 |
-0.7 |
-0.7 |
|
0.4 |
0.3 |
-0.3 |
-0.4 |
|
0.1 |
0.1 |
-0.5 |
-0.5 |
|
-0.2 |
0.0 |
-0.8 |
-0.9 |
|
0.2 |
0.2 |
-0.9 |
-0.8 |
|
0.5 |
0.5 |
0.1 |
0.2 |
|
-0.2 |
-0.2 |
0.3 |
0.5 |
|
0.6 |
0.4 |
-0.3 |
-0.1 |
|
0.7 |
0.7 |
0.9 |
1.1 |
|
-0.7 |
-0.6 |
0.8 |
0.7 |
|
0.0 |
0.0 |
0.6 |
0.6 |
|
0.1 |
0.0 |
0.8 |
0.6 |
|
-0.5 |
-0.5 |
0.3 |
0.0 |
|
-0.2 |
-0.2 |
-0.8 |
-0.8 |
|
0.0 |
0.0 |
-0.6 |
-0.7 |
GDP and expenditure components in the fourth quarter of 2024 in millions of euro, seasonally adjusted, at current prices |
||
---|---|---|
Euro area |
EU |
|
3 842 814.3 |
4 554 634.3 |
|
2 024 932.4 |
2 398 469.8 |
|
833 197.8 |
984 292.3 |
|
812 092.5 |
966 319.8 |
|
15 154.4 |
16 603.6 |
|
3 685 377.1 |
4 365 685.4 |
|
1 883 480.2 |
2 285 049.0 |
|
1 726 043.0 |
2 096 100.1 |
Notes for users
Revisions
The reliability of GDP and employment flash estimates was tested by dedicated working groups and revisions of subsequent estimates are continuously monitored. Further information can be found on Eurostat website.
With these estimates, euro area and EU employment and GDP figures for earlier quarters are revised.
Flash estimates of employment and GDP growth were published in News Release issued on 14 February 2025. They were based on a more limited data set than the one used for the present News Release and additionally, on preliminary estimates that have now been revised by some Member States. Revisions for the last quarter are highlighted in bold in the table below:
To the previous quarter (Q/Q-1) |
To the previous year (Q/Q-4) |
||||||
Previous |
Current |
Previous |
Current |
||||
Euro area |
EU |
Euro area |
EU |
Euro area |
EU |
Euro area |
EU |
0.1 |
0.2 |
0.2 |
0.4 |
0.9 |
1.1 |
1.2 |
1.4 |
0.1 |
0.1 |
0.1 |
0.2 |
0.6 |
0.5 |
0.7 |
0.5 |
All estimates presented in this release may be revised with the t+110 database update scheduled for 16 April 2025.
Release schedule
This news release presents estimates for euro area and EU GDP and employment aggregates based on national accounts transmission from all Member States due after t+2 months.
A further estimation is done at around t+110 days after some countries transmit updated estimates.
To increase the timeliness of key indicators, Eurostat also publishes flash estimates for GDP (after around 30 and 45 days) and employment (after around 45 days). The flash estimates are based on estimates provided by most EU Member States on a voluntary basis.
Methods and definitions
European quarterly national accounts are compiled in accordance with the European System of Accounts 2010 (ESA 2010). They include key policy indicators on GDP and employment.
Gross domestic product (GDP) at market prices measures the production activity of resident producer units. Growth rates are based on chain-linked volumes.
Employment covers employees and self-employed working in resident production units (domestic concept). Employment flash estimates are limited to total employment in persons, but regular estimates also cover hours worked and industry breakdowns.
Labour productivity is compiled as the ratio of economic output (GDP, chain-linked volumes with reference year 2010) to labour input (total employment measured in persons or hours worked, for all industries, according to the domestic concept).
The method used for compilation of European GDP and employment estimates is the same as for previous releases.
Geographical information
Euro area (EA20): Belgium, Germany, Estonia, Ireland, Greece, Spain, France, Croatia, Italy, Cyprus, Latvia, Lithuania, Luxembourg, Malta, the Netherlands, Austria, Portugal, Slovenia, Slovakia and Finland.
European Union (EU27): Belgium, Bulgaria, Czechia, Denmark, Germany, Estonia, Ireland, Greece, Spain, France, Croatia, Italy, Cyprus, Latvia, Lithuania, Luxembourg, Hungary, Malta, the Netherlands, Austria, Poland, Portugal, Romania, Slovenia, Slovakia, Finland and Sweden.
For more information
Share the release
Share component will be rendered here.
* Here the title * … *
… * * Here the logo and notes * */ function tableConfiguration() { /** Retrieves the list of table elements (images) */ const tables = document.getElementsByTagName(‘table’); /** We go through the list of tables */ for (let table of tables) { /** We create a section to wrap the table */ let section = document.createElement(‘section’); /** Add table-wrapper class to section element */ section.classList.add(‘table-wrapper’); /** We create a caption element to place the title */ let caption = document.createElement(‘caption’); /** We create thead element to place the headers */ let tHead = document.createElement(‘thead’); /** We create a footer to place notes, datasource and logo */ let footer = document.createElement(‘footer’); /** Retrieves the tBody */ let tBody = table.tBodies[0]; /** Retrieves the table rows */ let rows = tBody.rows; let datalabels = []; let captionContent = []; /** Stores the indexes of the rows to be removed after processing the whole table */ let rowsToRemove = []; /** We go through the rows within the table and extract caption, headers and footnotes */ buildTable(rows, captionContent, datalabels, footer, rowsToRemove); deleteRows(table, rowsToRemove); addTableCaption(caption, captionContent); addTableHeaders(table, tHead, datalabels); wrapInSection(section, table, caption, tHead, tBody, footer); linkHeaders(table); } } /** * Builds a table with the expected format: adding caption, datalabels and footer * @param {*} rows – The table rows * @param {*} captionContent – The content of the caption (title) * @param {*} datalabels – The list of datalabels (table headers) * @param {*} footer – The footer element * @param {*} rowsToRemove – Array containing the index of the rows to be removed */ function buildTable(rows, captionContent, datalabels, footer, rowsToRemove) { let rowIndex = 0; for (let row of rows) { let cells = row.cells; /** We check the first cell in order to guess the cell type: th, td; and cell classes: title, datalabel… */ let firstCell = row.firstElementChild; /** If the th class name is title, we convert this th into a caption */ if (isCaption(firstCell)) { addCaption(cells, captionContent, rowIndex, rowsToRemove) } /** If the th class name is datalabel, we add the header to the tHead component */ else if (isDatalabel(firstCell)) { addDatalabels(row, datalabels, rowIndex, rowsToRemove); } /** If the th class name is title, we convert this th into a caption */ else if (isFooter(firstCell)) { addFooter(row, footer, rowIndex, rowsToRemove); } else { row.setAttribute(‘initial-position’, rowIndex); } rowIndex++; } } /** * Checks whether the given cell has the given tagName and className * @param {*} cell – The cell to be checked * @param {*} tagName – The tag name to be checked * @param {*} className – The class name to be checked * @returns true if the cell’s tagName and className matches the given ones, false otherwise */ function checkCell(cell, tagName, className) { return cell.tagName.toLowerCase() === tagName && cell.className.indexOf(className) > -1; } /** * Whether a cell is a caption (title) * @param {*} cell – The cell to be checked * @returns true if the cell is a caption, false otherwise */ function isCaption(cell) { return checkCell(cell, ‘th’, ‘title’); } /** * Whether a cell is a datalabel * @param {*} cell – The cell to be checked * @returns true if the cell is a datalabel, false otherwise */ function isDatalabel(cell) { return checkCell(cell, ‘th’, ‘datalabel’); } /** * Whether a cell is a vertical header * @param {*} cell – The cell to be checked * @returns true if the cell is a vertical header, false otherwise */ function isVerticalHeader(cell) { return checkCell(cell, ‘th’, ‘vertical-header’); } /** * Whether a cell is a footer * @param {*} cell – The cell to be checked * @returns true if the cell is a footer, false otherwise */ function isFooter(cell) { return checkCell(cell, ‘td’, ‘footer’); } /** * Adds the content of the caption cells: paragraphs * @param {*} cells – The cells belonging to the row * @param {*} captionContent – The content of the caption * @param {*} rowIndex – The index of current row * @param {*} rowsToRemove – Array containing the index of the rows to be removed */ function addCaption(cells, captionContent, rowIndex, rowsToRemove) { for (let cell of cells) { /** We must add all the Child Nodes of each th title Cell */ for (let childNode of cell.childNodes) { captionContent.push(childNode); } } /** We remove the row from within the tables as now it’s out in the caption */ rowsToRemove.push(rowIndex); } /** * Adds the row as a datalabel * @param {*} row – The current row * @param {*} datalabels – List of datalabels * @param {*} rowIndex – The index of current row * @param {*} rowsToRemove – Array containing the index of the rows to be removed */ function addDatalabels(row, datalabels, rowIndex, rowsToRemove) { datalabels.push(row); /** We remove the row from within the tables as now it’s out in the caption */ rowsToRemove.push(rowIndex); } /** * Adds the notes and logo * @param {*} row – The current row * @param {*} footer – The footer of the table * @param {*} rowIndex – The index of current row * @param {*} rowsToRemove – Array containing the index of the rows to be removed */ function addFooter(row, footer, rowIndex, rowsToRemove) { /** We create a div element for notes and logo */ const notes = document.createElement(‘div’); notes.classList.add(‘footer-element’, ‘notes’); /** We add the content to the new note element */ notes.innerHTML = row.firstElementChild.innerHTML; /** We create a footer to place notes, datasource and logo */ footer.appendChild(notes); /** We remove the row from within the tables as now it’s out in the footer */ rowsToRemove.push(rowIndex); } /** * Deletes the rows which data has been moved to either caption, tHead or footer * @param {*} table – The current table * @param {*} rowsToRemove – Array containing the index of the rows to be removed */ function deleteRows(table, rowsToRemove) { /** We go through the title rows and append them to the caption element */ for (let j = rowsToRemove.length – 1; j >= 0; j–) { table.deleteRow(rowsToRemove[j]); } } /** * Adds the caption to the table. * @param {*} caption – The caption dom element * @param {*} captionContent – The content of the caption */ function addTableCaption(caption, captionContent) { /** We go through the Caption Content and append the nodes to the caption element */ for (let node of captionContent) { caption.appendChild(node); } } /** * Adds the headers to the table * @param {*} table – The table to make sortable * @param {*} tHead – The thead dom element * @param {*} datalabels – The datalabels to be added (headers) */ function addTableHeaders(table, tHead, dataLabels) { let sortable = false; /** We go through the header rows and append them to the tHead element */ for (let dataLabelRow of dataLabels) { let cells = dataLabelRow.cells; for (let th of cells) { if (th.classList.contains(‘sortable’)) { sortable = true; let button = createNewSortButton(); th.appendChild(button); } } tHead.appendChild(dataLabelRow); } if (sortable) { table.classList.add(‘sortable’); } } function createNewSortButton() { // creates sort button const button = document.createElement(‘button’); button.classList.add(‘ecl-table__arrow’); // creates a generic svg element for the two arrows const svgIconUp = document.createElementNS(‘http://www.w3.org/2000/svg’, ‘svg’); svgIconUp.setAttribute(‘xml:space’, ‘preserve’); svgIconUp.setAttribute(‘viewBox’, ‘0 0 24 24’); svgIconUp.setAttribute(‘enable-background’, ‘new 0 0 24 24’); svgIconUp.setAttribute(‘focusable’, ‘false’); svgIconUp.setAttribute(‘aria-hidden’, ‘true’); svgIconUp.setAttribute(‘class’, ‘ecl-table__icon ecl-icon ecl-icon–m’); // adds path element of the arrow to the arrow svg const pathIconArrow = document.createElementNS(‘http://www.w3.org/2000/svg’, ‘path’); pathIconArrow.setAttribute(‘d’, ‘M7.4 13 11 9.4c.5-.5 1.4-.5 2 0l3.6 3.6c.9.9.2 2.4-1 2.4H8.4c-1.3 0-1.9-1.5-1-2.4’); svgIconUp.appendChild(pathIconArrow); // clones the generic arrow svg including the child path also const svgIconDown = svgIconUp.cloneNode(true); // seups the arrow directions to up and down by extra css classes svgIconUp.classList.add(‘ecl-table__icon-up’); svgIconDown.classList.add(‘ecl-table__icon-down’); // insert the two arrow svg elements into the button button.appendChild(svgIconUp); button.appendChild(svgIconDown); return button; } /** * Places all the elements in their places and wraps the table into a section. * @param {*} section – The section (dom element) which will wrap table and footer * @param {*} table – The table to be wrapped * @param {*} caption – The caption (dom element) to be added to the table * @param {*} tHead – The thead (dom element) to be added to the table * @param {*} tBody – The tbody (dom element) to be added to the table * @param {*} footer – The footer (dom element) to be added to the section */ function wrapInSection(section, table, caption, tHead, tBody, footer) { /** We insert caption and thead before tbody */ table.insertBefore(caption, tBody); table.insertBefore(tHead, tBody); /** We wrap the table into a section */ table.parentNode.insertBefore(section, table); section.appendChild(table); section.appendChild(footer); } /** * Adds ids and header attributes to link every cell to all related headers so that machines can correctly read the figures. * @param {*} table – The table to be wrapped */ function linkHeaders(table) { const headers = getHeaders(table.tHead); const tBody = table.tBodies ? table.tBodies[0] : null; addHeaderLinks(tBody, headers); } function getHeaders(tHead) { const headers = []; if (tHead) { let i = 0; for (let row of tHead.rows) { /** We add a new row in the headers array */ headers.push([]); /** Stores the header ids and colSpan so we can guess to which cells (td) we must add the headers */ let j = 0; for (const cell of row.cells) { cell.setAttribute(‘id’, ‘h_’ + i + ‘_’ + j); headers[i].push({ id: cell.id, colSpan: cell.colSpan ? cell.colSpan : 1 }); j++; } i++; } } return headers; } function addHeaderLinks(tBody, headers) { if (tBody) { let i = 0; for (let row of tBody.rows) { let j = 0; for (const cell of row.cells) { /** If the cell is a vertical header we add its id */ if (cell.className.indexOf(‘vertical-header’) > -1) { cell.setAttribute(‘id’, ‘vh_’ + i + ‘_’ + j); } const headerLinks = getHeaderLinks(headers, j, cell.colSpan, row.cells[0]); cell.setAttribute(‘headers’, headerLinks); j++; } i++; } } } /** * Retrieves the header (ths) ids in order to link them to a specific cell (td) * @param {*} rows – The rows containing all headers * @param {*} index – The index of the specific cell * @param {*} colSpan – The colspan of the specific cell * @param {*} firstCell – The first cell of the row. Used to reference possible vertical headers * @returns A string containing the list of header ids split by spaces */ function getHeaderLinks(rows, index, colSpan, firstCell) { /** It will contain the header ids */ let links = ”; /** We add the reference of the vertical header if there is */ if (index > 0 && firstCell.className.indexOf(‘vertical-header’) > -1) { links = firstCell.id; } /** We go through the list of header rows */ for (const headers of rows) { /** Accumulates the colspan of the checked headers */ let sumColSpan = 0; /** We go through the list of headers for the specific header row */ for (const header of headers) { /** We check that the index of the cell belongs to a specific column */ if (index >= sumColSpan && index chartObj.resize()).observe(chartDiv); } } /** * Customizes the chart by applying custom events, axis formats, tooltips, and axis labels. * @param option – The chart options object. */ function customChartOptions(option) { setClickableDatasourceLinks(option); setAxisFormatter(option); setTooltipFormatter(option); } /** * Attaches event handlers to a chart: ‘legendselectchanged’. * * @param {Chart} chart – The chart object. */ function addEventHandlers(chart) { /** Attach an event handler for the ‘legendselectchanged’ event */ chart.on(‘legendselectchanged’, (event) => { /** Call the onChartLegendSelected function with the event and chart object */ onChartLegendSelected(event, chart); }); } /** * Handles the legend selected changed event of the chart. * @param {any} event – The event object containing the selected legend items. * @param {any} chart – The chart object. */ function onChartLegendSelected(event, chart) { /** Get the selected legend items */ const selected = event.selected; /** Count the number of selected legend items */ const selectedCount = Object.values(selected).filter(Boolean).length; /** If all legend items are deselected, keep the selection on the last clicked item */ if (selectedCount === 0) { selected[event.name] = true; } /** Update the legend selection */ chart.setOption({ legend: { selected: selected } }); } /** * Attaches custom events to the provided option object. * * @param {object} option – The option object to attach custom events to. */ function setClickableDatasourceLinks(option) { /** If the table has datasource link */ if (option.graphic && option.graphic.length >= 3) { /** Attach an onclick event handler to the third element of the graphic array (datasource links) */ option.graphic[2].onclick = function (event) { /** If the element has a link defined in its style */ if (this.style?.link) { /** Open the link in a new tab/window */ window.open(this.style.link, ‘_blank’); } }; } } /** * Sets the default axis formatter for axis labels. * @param {object} option – The option object to update the axis formatter * */ function setAxisFormatter(option) { /** The default unit used in axis labels */ const defaultUnit = ‘%’; /** If the yAxis are used as values */ if (option.yAxis.type === ‘value’) { /** If the yAxis unit is not defined, set % as default */ option.yAxis.axisLabel.unit = option.yAxis.axisLabel.unit ? option.yAxis.axisLabel.unit : defaultUnit; /** If the yAxis label padding is not defined, set 15 as default suffix */ option.yAxis.axisLabel.padding = option.yAxis?.axisLabel?.padding ? option.yAxis.axisLabel.padding : 15; /** Use the custom formatter */ option.yAxis.axisLabel.formatter = (value) => customAxisFormatter(option.lang, value, option.yAxis.axisLabel.unit, parseInt(option.yAxis.axisLabel.decimals)); // Use the custom formatter } /** If the xAxis are used as values */ if (option.xAxis.type === ‘value’) { /** If the xAxis unit is not defined, set % as default */ option.xAxis.axisLabel.unit = option.xAxis.axisLabel.unit ? option.xAxis.axisLabel.unit : defaultUnit; /** Use the custom formatter */ option.xAxis.axisLabel.formatter = (value) => customAxisFormatter(option.lang, value, option.xAxis.axisLabel.unit, parseInt(option.xAxis.axisLabel.decimals)); } /** If xAxis type is category */ else if (option.xAxis.type === ‘category’) { boldCountries(option); } } /** * Formats a numeric value with a specified unit and decimal precision. * * @param {number} value – The numeric value to be formatted. * @param {string} unit – The unit to be appended to the formatted value. * @param {number} decimals – The number of decimal places to round the value to. * @returns {string} The formatted string representation of the value with unit. */ function customAxisFormatter(lang, value, unit, decimals) { /** * Check the language and format the value accordingly. * For French (fr) and German (de), use commas instead of dots. * For other languages (en), use the default format with dots. */ const formattedValue = lang === ‘fr’ || lang === ‘de’ ? `${value.toFixed(decimals).replace(‘.’, ‘,’)}${unit}` : `${value.toFixed(decimals)}${unit}`; return formattedValue; } /** * Enriches the x-axis labels with formatting based on certain values. * If EU and Euro Area are included, those must be written in bold * @remarks * This function enriches the x-axis labels with formatting based on certain values, such as making “EU” and “Euro Area” bold. * @param {object} option – The option object to set bold countries to. */ function boldCountries(option) { option.xAxis.axisLabel.formatter = function (v) { /** Convert input string to lowercase for case-insensitive comparison */ const lowerCaseV = v ? v.toLowerCase() : ”; /** Check for specific label values and format them accordingly, check for “EU” or “UE” */ if (lowerCaseV === “eu” || lowerCaseV === “ue”) { // return `{eu|${v}}`; } /** Check for “Euro Area”, “Euroraum”, or “Zone Euro” */ else if (lowerCaseV === “euro area” || lowerCaseV === “euroraum” || lowerCaseV === “zone euro”) { return `{euroArea|${v}}`; } return v; }; /** Set the rich property of the axis label to apply the bold formatting */ option.xAxis.axisLabel.rich = { eu: { fontWeight: “bold”, }, euroArea: { fontWeight: “bold” } }; } /** * Handles formatting the tooltip decimal convention in the graphic. * @remarks * This function formats the tooltip based on the language and decimal convention. * * @param {object} option – The option object to add custom tooltip. */ function setTooltipFormatter(option) { /** * Tooltip formatter for ECharts. * @param {object[]} params – Parameters for the tooltip formatter. * @param {string} params[].name – Name of the x-axis value. * @param {string} params[].seriesName – Name of the series. * @param {number} params[].value – Value of the data point. * @param {string} params[].color – Color of the series. * @param {string} ticket – Ticket for the callback. * @param {Function} callback – Callback function. * @returns {string} – Formatted tooltip content. */ option.tooltip.formatter = function (params, ticket, callback) { /** Retrieve the x-axis value for the tooltip */ const xAxisValue = params[0].name; /** If xAxisValue is empty, return null to hide the tooltip */ if (!xAxisValue) { return null; } /** Create the tooltip content container with a white background and padding */ let tooltipContent = ”; /** Add the x-axis value to the tooltip content */ /** @type {string} XAxis */ tooltipContent += ” + xAxisValue + ‘]]>‘; /** Retrieve the order from the tooltip option */ const sortOrder = option.tooltip.order; /** Sort the ‘params’ array based on the ‘sortOrder’ parameter. */ switch (sortOrder) { /** Sort by series name in ascending order. */ case ‘seriesAsc’: params = params.sort((a, b) => a.seriesName.localeCompare(b.seriesName)); break; /** Sort by series name in descending order. */ case ‘seriesDesc’: params = params.sort((a, b) => b.seriesName.localeCompare(a.seriesName)); break; /** Sort by numerical value in ascending order. */ case ‘valueAsc’: params = params.sort((a, b) => parseFloat(a.value) – parseFloat(b.value)); break; /** Sort by numerical value in descending order. */ case ‘valueDesc’: params = params.sort((a, b) => parseFloat(b.value) – parseFloat(a.value)); break; /** Reverse the current order. */ case ‘reverse’: params.reverse(); break; default: break; } /** Iterate over each series in the tooltip parameters */ for (const param of params) { /** Retrieve the name and value of the current series */ let seriesName = param.seriesName; let value = param.value; /** Replace every specific apostrphe by simple one. */ seriesName = seriesName.replaceAll(“’”, “‘”); /** Convert the numeric value to its string representation. */ const strValue = String(value); /** Retrieve the axis used as value */ const axis = option.yAxis.type === ‘value’ ? option.yAxis : option.xAxis; /** Initialize the number of decimal places */ let decimals = option.tooltip.decimals; /** Check if decimals configuration is set to default and the value contains decimal places */ if (!decimals && strValue.indexOf(‘.’) > -1) { /** Calculate the number of decimal places */ decimals = strValue.substring(strValue.indexOf(‘.’), strValue.length – 1).length; } else { /** If there are no decimal places, format the value with 1 decimal place */ decimals = decimals || 1; /** Convert the value to a fixed-point notation string with a specified number of decimal places. */ value = Number(value).toFixed(decimals); } /** Convert -0 value to 0 with the specified or calculated number of decimal places.*/ if (Number(value) == -0) { value = (Number(value) + 0).toFixed(decimals); } /** Extract the unit from within the axis label */ const unit = axis.axisLabel.unit ? axis.axisLabel.unit : ”; /** Format the value using the appropriate number of decimal places */ if (isNaN(value)) { value = ‘N/A’; } else { value = Number(value).toLocaleString(option.lang ? option.lang : ‘en’, { minimumFractionDigits: decimals }) + unit; } /** Retrieve the color of the current series */ const color = param.color; /** * Add the series name and value to the tooltip content * Use a circle icon with the series color */ tooltipContent += ‘
‘ + ” + ” + ” + seriesName + ” + ” + ” + value + ” + ‘
‘; } /** Close the tooltip content container */ tooltipContent += ”; /** Return the formatted tooltip content */ return tooltipContent; } } /* * This content is licensed according to the W3C Software License at * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document * * File: sortable-table.js * * Desc: Adds sorting to a HTML data table that implements ARIA Authoring Practices */ class SortableTable { constructor(tableNode) { this.tableNode = tableNode; this.columnHeaders = tableNode.querySelectorAll(‘thead th.sortable’); this.sortColumns = []; for (let i = 0; i b.value ? -1 : 1; } } else if (isNumber) { return a.value – b.value; } else { return a.value
Subscribe to receive the latest Eurostat Euro indicators releases
{ if (document.querySelector(selector)) { return resolve(document.querySelector(selector)); } const observer = new MutationObserver(mutations => { if (document.querySelector(selector)) { resolve(document.querySelector(selector)); observer.disconnect(); } }); observer.observe(document.body, { childList: true, subtree: true }); }); } waitForElm(‘div.chart’).then((elm) => { // Has to be run after cool-ngx-editor.js script that is tweeking the charts const elements = document.getElementsByClassName(“chart”); for (let i = 0; i < elements.length; i++) { let div = document.createElement('div'); div.id = "share-chart-" + i; div.style = "position: absolute; right: 0; z-index: 50;"; elements[i].prepend(div); let script = document.createElement('script'); script.type = "application/json"; let url = new URL(window.location.href); url.searchParams.set('item', 'chart'); url.searchParams.set('id', i); let code = '{"service": "sbkm", "version": "2.0", "popup": false, "icon": true, "more" : ["facebook", "x", "linkedin", "email"], "renderTo": "' + div.id + '", "to": ["more"], "target": true, "link": "' + url.href + '", "via": "EU_Eurostat", "title": "' + getJournalArticleTitle() + '"}'; try { script.appendChild(document.createTextNode(code)); } catch (e) { s.text = code; } elements[i].parentNode.insertBefore(script, elements[i].nextSibling); } }); // Add share button to tables $(document).ready(function() { // Has to be run after cool-ngx-editor.js script that is tweeking the tables const tables = document.getElementsByTagName("table"); for (let i = 0; i position) { await new Promise(r => setTimeout(r, 500)); // Wait a bit so that it doesn’t scroll too far allItems[position].scrollIntoView(true); } } });;}());]]>