diff --git a/src/app/api/configuration.api.ts b/src/app/api/configuration.api.ts
index b134ce55e56951497fbafb46c727d9739d27cad6..fd761e3194002159711e4140edf82603bbbc1736 100644
--- a/src/app/api/configuration.api.ts
+++ b/src/app/api/configuration.api.ts
@@ -9,7 +9,7 @@ import {
 } from '../models/configuration';
 import { ApiResponse } from '../models/api-response';
 
-export const CONFIGURATION_API_URL = '/configurations';
+export const CONFIGURATION_API_URL = '/api/configurations';
 
 @Injectable({
   providedIn: 'root',
diff --git a/src/app/api/dashboard.api.ts b/src/app/api/dashboard.api.ts
index 42a065716b18753ed0e7c7182cdf2485e2d4d673..2706cacd2ff445925922db8d36199a93ccdf73ae 100644
--- a/src/app/api/dashboard.api.ts
+++ b/src/app/api/dashboard.api.ts
@@ -1,12 +1,17 @@
-import { inject, Injectable } from '@angular/core';
-import { HttpClient } from '@angular/common/http';
 import { ApiResponse } from '../models/api-response';
 import { ChartFrames } from '../models/chart-frames';
 import { map, Observable, tap } from 'rxjs';
 import { ChartInformationRate } from '../models/chart-information-rate';
 import { ChartProtocol } from '../models/chart-protocol';
+import { inject, Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import {
+  DashboardStatistics,
+  DashboardStatisticsDto,
+  dtoToDashboardStatistics,
+} from '../models/dashboard-statistics';
 
-export const DASHBOARD_API_URL = '/statistics';
+export const DASHBOARD_API_URL = '/api/statistics';
 
 @Injectable({
   providedIn: 'root',
@@ -14,6 +19,12 @@ export const DASHBOARD_API_URL = '/statistics';
 export class DashboardApi {
   private readonly httpClient = inject(HttpClient);
 
+  fetchStatistics(): Observable<DashboardStatistics> {
+    return this.httpClient
+      .get<ApiResponse<DashboardStatisticsDto>>(DASHBOARD_API_URL)
+      .pipe(map(dto => dtoToDashboardStatistics(dto.data)));
+  }
+
   fetchFramesHistory(interval: number): Observable<ChartFrames[]> {
     return this.httpClient
       .get<ApiResponse<ChartFrames[]>>(
diff --git a/src/app/components/configuration/configuration.component.ts b/src/app/components/configuration/configuration.component.ts
index 58830a5b714c0d3dddbfbbf12d3b2585619eeabc..910833bff1914b10cf030a4b681c3ae0eed406db 100644
--- a/src/app/components/configuration/configuration.component.ts
+++ b/src/app/components/configuration/configuration.component.ts
@@ -1,9 +1,9 @@
 import {
-  afterNextRender,
   ChangeDetectionStrategy,
   Component,
   effect,
   inject,
+  OnInit,
   signal,
 } from '@angular/core';
 import { PageWrapperComponent } from '../page-wrapper/page-wrapper.component';
@@ -50,7 +50,7 @@ enum ConfigurationPageMode {
   styleUrl: './configuration.component.scss',
   changeDetection: ChangeDetectionStrategy.OnPush,
 })
-export class ConfigurationComponent {
+export class ConfigurationComponent implements OnInit {
   configurationApi = inject(ConfigurationApi);
 
   pageMode = signal<ConfigurationPageMode>(ConfigurationPageMode.READ);
@@ -70,27 +70,15 @@ export class ConfigurationComponent {
         });
       }
     });
+  }
 
-    afterNextRender(() => {
-      this.fetchConfigurationOptions().subscribe(configurations => {
-        const appliedConfiguration = configurations.find(c => c.is_applied);
-        if (appliedConfiguration) {
-          this.chosenConfiguration.set(appliedConfiguration.id);
-        }
-        this.configurationOptions.set(configurations);
-      });
-    });
+  ngOnInit() {
+    this.updateConfigurationOptions();
   }
 
   onDeleteConfiguration() {
     this.configurationApi.delete(this.chosenConfiguration()!).subscribe(() => {
-      this.fetchConfigurationOptions().subscribe(configurations => {
-        const appliedConfiguration = configurations.find(c => c.is_applied);
-        if (appliedConfiguration) {
-          this.chosenConfiguration.set(appliedConfiguration.id);
-        }
-        this.configurationOptions.set(configurations);
-      });
+      this.updateConfigurationOptions();
     });
   }
 
@@ -128,5 +116,15 @@ export class ConfigurationComponent {
     );
   }
 
+  private updateConfigurationOptions() {
+    this.fetchConfigurationOptions().subscribe(configurations => {
+      const appliedConfiguration = configurations.find(c => c.is_applied);
+      if (appliedConfiguration) {
+        this.chosenConfiguration.set(appliedConfiguration.id);
+      }
+      this.configurationOptions.set(configurations);
+    });
+  }
+
   protected readonly ConfigurationPageMode = ConfigurationPageMode;
 }
diff --git a/src/app/components/dashboard-statistics/dashboard-statistics.component.html b/src/app/components/dashboard-statistics/dashboard-statistics.component.html
index 12e92e1088a4c2ca23c5013fbb799f1c49dbcb2e..bd5d0df4699d5f06ed48f2a9e093d3c5bfcfa6ae 100644
--- a/src/app/components/dashboard-statistics/dashboard-statistics.component.html
+++ b/src/app/components/dashboard-statistics/dashboard-statistics.component.html
@@ -1 +1,77 @@
-<ngx-skeleton-loader count="10" />
+<div class="statistics">
+  @let statistics = dashboardStatistics | async;
+  @if (!statistics) {
+    <div class="statistics__loader">
+      @for (_ of [].constructor(4); track $index) {
+        <ngx-skeleton-loader count="7" />
+      }
+    </div>
+  }
+  @else {
+    <div class="statistics__table">
+      <div class="statistics__table__time">
+        <p>Total time: {{ statistics.total_time | time }} </p>
+      </div>
+      <table class="statistics__table__header">
+        <thead class="statistics__table__header-title">
+          <tr>
+            <th></th>
+            <th>Total packets</th>
+            <th>Packets per second</th>
+            <th>Total bytes</th>
+            <th>Bytes per second</th>
+          </tr>
+        </thead>
+        <tbody>
+          @let protocolEth = getETHStatistics(statistics.protocols);
+          <tr class="statistics__table__header-eth">
+            <td>{{ protocolEth.name }}</td>
+            <td>{{ protocolEth.total_packets | decimal }}</td>
+            <td>
+              {{ getPerSecond(protocolEth.total_packets, statistics.total_time) | decimal }}
+            </td>
+            <td>{{ protocolEth.total_bytes | decimal }}</td>
+            <td>
+              {{ getPerSecond(protocolEth.total_bytes, statistics.total_time) | decimal }}
+            </td>
+          </tr>
+        </tbody>
+      </table>
+      <table class="statistics__table__protocols">
+        <tbody>
+        @for (protocol of getProtocols(statistics.protocols); track protocol.name) {
+            <tr>
+              <td>{{ protocol.name }}</td>
+              <td>{{ protocol.total_packets | decimal }}</td>
+              <td>
+                {{ getPerSecond(protocol.total_packets, statistics.total_time) | decimal }}
+              </td>
+              <td>{{ protocol.total_bytes | decimal }}</td>
+              <td>
+                {{ getPerSecond(protocol.total_bytes, statistics.total_time) | decimal }}
+              </td>
+            </tr>
+        }
+        </tbody>
+      </table>
+      <table class="statistics__table__ir">
+        <thead class="statistics__table__ir-header">
+        <tr>
+          <th></th>
+          <th>Min</th>
+          <th>Max</th>
+          <th>Current</th>
+        </tr>
+        </thead>
+        <tbody>
+          <tr class="statistics__table_ir-content">
+            <td>Information Rate</td>
+            <td>{{ statistics.information_rate.min | decimal }}</td>
+            <td>{{ statistics.information_rate.max | decimal }}</td>
+            <td>{{ statistics.information_rate.current | decimal }}</td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+  }
+</div>
diff --git a/src/app/components/dashboard-statistics/dashboard-statistics.component.scss b/src/app/components/dashboard-statistics/dashboard-statistics.component.scss
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e11b5db12cf23fcea68df59b4eba90d9989305d9 100644
--- a/src/app/components/dashboard-statistics/dashboard-statistics.component.scss
+++ b/src/app/components/dashboard-statistics/dashboard-statistics.component.scss
@@ -0,0 +1,89 @@
+@use '../../../vars';
+@use 'sass:map';
+
+:host {
+  ngx-skeleton-loader {
+    display: flex;
+    flex-direction: row;
+    gap: map.get(vars.$spacing, 'md');
+    ::ng-deep * {
+      height: 50px;
+    }
+  }
+
+  .statistics {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    font-weight: 500;
+    font-size: map.get(vars.$text, 'lg');
+
+    &__table {
+      &__time {
+        font-size: map.get(vars.$text, 'md');
+      }
+
+      &__header {
+        width: 100%;
+        border-radius: map.get(vars.$radius, 'xs');
+        background-color: map.get(vars.$grey, 0);
+        padding: map.get(vars.$spacing, 'none') map.get(vars.$spacing, 'xl');
+
+        &-title {
+          border-radius: map.get(vars.$radius, 'xs');
+          background-color: map.get(vars.$grey, 0);
+          padding: map.get(vars.$spacing, 'none') map.get(vars.$spacing, 'xl');
+        }
+
+        &-eth td {
+          border-top: 1px solid map.get(vars.$grey, 30);
+        }
+
+        th, td {
+          width: 20%;
+          padding: map.get(vars.$spacing, 'sm');
+          text-align: left;
+        }
+
+      }
+
+      &__protocols {
+        border-radius: map.get(vars.$radius, 'xs');
+        background-color: map.get(vars.$grey, 0);
+        padding: map.get(vars.$spacing, 'none') map.get(vars.$spacing, 'xl');
+
+        margin-top: map.get(vars.$text, 'lg');
+        width: 100%;
+
+        th, td {
+          width: 20%;
+          padding: map.get(vars.$spacing, 'sm');
+          text-align: left;
+        }
+
+        tr:not(:last-child) td {
+          border-bottom: 1px solid map.get(vars.$grey, 30);
+        }
+      }
+
+      &__ir {
+        border-radius: map.get(vars.$radius, 'xs');
+        background-color: map.get(vars.$grey, 0);
+        padding: map.get(vars.$spacing, 'none') map.get(vars.$spacing, 'xl');
+
+        margin-top: map.get(vars.$spacing, 'lg');
+        width: 100%;
+
+        tbody td {
+          border-top: 1px solid map.get(vars.$grey, 30);
+        }
+
+        th, td {
+          width: 25%;
+          padding: map.get(vars.$spacing, 'sm');
+          text-align: left;
+        }
+      }
+    }
+  }
+}
diff --git a/src/app/components/dashboard-statistics/dashboard-statistics.component.ts b/src/app/components/dashboard-statistics/dashboard-statistics.component.ts
index 975f49c33dc444132cf28267b37526124407a9b7..2b6f6289f1cb04b49be36b8caebc8bea25d85bfa 100644
--- a/src/app/components/dashboard-statistics/dashboard-statistics.component.ts
+++ b/src/app/components/dashboard-statistics/dashboard-statistics.component.ts
@@ -1,11 +1,37 @@
-import { ChangeDetectionStrategy, Component } from '@angular/core';
+import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
 import { NgxSkeletonLoaderComponent } from 'ngx-skeleton-loader';
+import { AsyncPipe } from '@angular/common';
+import { DashboardApi } from '../../api/dashboard.api';
+import { interval, shareReplay, switchMap } from 'rxjs';
+import { ProtocolStatistics } from '../../models/dashboard-statistics';
+import { TimePipe } from '../../pipes/time.pipe';
+import { DecimalPipe } from '../../pipes/decimal.pipe';
 
 @Component({
   selector: 'app-dashboard-statistics',
-  imports: [NgxSkeletonLoaderComponent],
+  imports: [NgxSkeletonLoaderComponent, AsyncPipe, TimePipe, DecimalPipe],
   templateUrl: './dashboard-statistics.component.html',
   styleUrl: './dashboard-statistics.component.scss',
   changeDetection: ChangeDetectionStrategy.OnPush,
 })
-export class DashboardStatisticsComponent {}
+export class DashboardStatisticsComponent {
+  dashboardApi = inject(DashboardApi);
+
+  dashboardStatistics = interval(1000).pipe(
+    switchMap(() => this.dashboardApi.fetchStatistics()),
+    shareReplay(1)
+  );
+
+  getPerSecond(value: number, time: Date): number {
+    const totalSeconds = time.getTime() / 1000;
+    return value / totalSeconds;
+  }
+
+  getETHStatistics(protocols: ProtocolStatistics[]): ProtocolStatistics {
+    return protocols.find(protocol => protocol.name === 'ETH')!;
+  }
+
+  getProtocols(protocols: ProtocolStatistics[]): ProtocolStatistics[] {
+    return protocols.filter(protocol => protocol.name !== 'ETH');
+  }
+}
diff --git a/src/app/components/dashboard/dashboard.component.scss b/src/app/components/dashboard/dashboard.component.scss
index 1938814a9ffa012336e43c56745f11cf1ea4b54c..d11c2b9c25b202716ae17166d1acf99a1ccdeb1e 100644
--- a/src/app/components/dashboard/dashboard.component.scss
+++ b/src/app/components/dashboard/dashboard.component.scss
@@ -29,6 +29,10 @@
     box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
     border-bottom: 1px solid map.get(vars.$grey, 30);
 
+    &-title {
+      font-size: map.get(vars.$text, 'lg');
+    }
+
     &:last-child {
       border-bottom: none;
     }
diff --git a/src/app/interceptor/interceptor.ts b/src/app/interceptor/interceptor.ts
index 21905b02b2b875fa4dbfb9ede7656b5ba6ec3fa1..f83b6314c8851c00741fab2c06a14b6822c7d7ca 100644
--- a/src/app/interceptor/interceptor.ts
+++ b/src/app/interceptor/interceptor.ts
@@ -7,42 +7,48 @@ import * as irCurrent from './mocks/ir-current.json';
 import * as irHistorical from './mocks/ir-historical.json';
 import * as ipv4Current from './mocks/ipv4-current.json';
 import * as ipv4Historical from './mocks/ipv4-historical.json';
+import * as dashboardStats from './mocks/dashboard-statistics.json';
+import * as dashboardStats2 from './mocks/dashboard-statistics-2.json';
 
 export const urls = [
   {
-    url: '/configurations/1abc',
-    json: configuration1,
+    url: '/api/configuration/1abc',
+    json: () => configuration1,
   },
   {
-    url: '/configurations/2def',
-    json: configuration2,
+    url: '/api/configuration/2def',
+    json: () => configuration2,
   },
   {
-    url: '/configurations',
-    json: configurationList,
+    url: '/api/configuration',
+    json: () => configurationList,
   },
   {
-    url: '/statistics/frames/current',
-    json: framesCurrent,
+    url: '/api/statistics/frames/current',
+    json: () => framesCurrent,
   },
   {
-    url: '/statistics/frames/historical',
-    json: framesHistorical,
+    url: '/api/statistics/frames/historical',
+    json: () => framesHistorical,
   },
   {
-    url: '/statistics/ir/current',
-    json: irCurrent,
+    url: '/api/statistics/ir/current',
+    json: () => irCurrent,
   },
   {
-    url: '/statistics/ir/historical',
-    json: irHistorical,
+    url: '/api/statistics/ir/historical',
+    json: () => irHistorical,
   },
   {
-    url: '/statistics/ipv4/current',
-    json: ipv4Current,
+    url: '/api/statistics/ipv4/current',
+    json: () => ipv4Current,
   },
   {
-    url: '/statistics/ipv4/historical',
-    json: ipv4Historical,
+    url: '/api/statistics/ipv4/historical',
+    json: () => ipv4Historical,
+  },
+  {
+    url: '/api/statistics',
+    json: () => (Math.random() < 0.5 ? dashboardStats2 : dashboardStats),
   },
 ];
diff --git a/src/app/interceptor/mock-interceptor.ts b/src/app/interceptor/mock-interceptor.ts
index a7c8d7b51b8951c31a20f285dcda4e588a9610d8..f4dc1a11cecbfd449140b9e199758083ddcdcd46 100644
--- a/src/app/interceptor/mock-interceptor.ts
+++ b/src/app/interceptor/mock-interceptor.ts
@@ -8,12 +8,12 @@ export const MockInterceptor: HttpInterceptorFn = (req, next) => {
   const { url, method } = req;
 
   for (const element of urls) {
-    let body = (element.json as any).default;
+    let body = (element.json() as any).default;
     if (url === DASHBOARD_API_URL + '/frames/current') {
       body = getRandomFrameRecord();
     }
     if (url.includes(element.url)) {
-      console.log('Loaded from json for url: ' + url, element.json, body);
+      console.log('Loaded from json for url: ' + url, element.json(), body);
       return of(new HttpResponse({ status: 200, body: body })).pipe(delay(300));
     }
   }
diff --git a/src/app/interceptor/mocks/dashboard-statistics-2.json b/src/app/interceptor/mocks/dashboard-statistics-2.json
new file mode 100644
index 0000000000000000000000000000000000000000..9d58d0f611f90c47edf6bbd676fde91d8058d2ea
--- /dev/null
+++ b/src/app/interceptor/mocks/dashboard-statistics-2.json
@@ -0,0 +1,33 @@
+{
+  "data": {
+    "id": "statistics",
+    "total-time": 160402,
+    "protocols": [
+      {
+        "name": "ETH",
+        "total-packets": 1237890,
+        "total-bytes": 123678901
+      },
+      {
+        "name": "TCP",
+        "total-packets": 323344,
+        "total-bytes": 32112345
+      },
+      {
+        "name": "IPv4",
+        "total-packets": 3399,
+        "total-bytes": 1000
+      },
+      {
+        "name": "IPv6",
+        "total-packets": 13,
+        "total-bytes": 778
+      }
+    ],
+    "information-rate": {
+      "min": 0,
+      "max": 10.53,
+      "current": 10.53
+    }
+  }
+}
diff --git a/src/app/interceptor/mocks/dashboard-statistics.json b/src/app/interceptor/mocks/dashboard-statistics.json
new file mode 100644
index 0000000000000000000000000000000000000000..b05d511f7456fb992cea4866fc92d248c29de429
--- /dev/null
+++ b/src/app/interceptor/mocks/dashboard-statistics.json
@@ -0,0 +1,33 @@
+{
+  "data": {
+    "id": "statistics",
+    "total-time": 160401,
+    "protocols": [
+        {
+          "name": "ETH",
+          "total-packets": 1234567,
+          "total-bytes": 123456789
+        },
+        {
+          "name": "TCP",
+          "total-packets": 321312,
+          "total-bytes": 32143245
+        },
+        {
+          "name": "IPv4",
+          "total-packets": 3333,
+          "total-bytes": 777
+        },
+        {
+          "name": "IPv6",
+          "total-packets": 0,
+          "total-bytes": 0
+        }
+      ],
+    "information-rate": {
+        "min": 0,
+        "max": 0,
+        "current": 0
+      }
+  }
+}
diff --git a/src/app/models/dashboard-statistics.ts b/src/app/models/dashboard-statistics.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3a8befc246d094db7c2a652aa599b2a4e49273cd
--- /dev/null
+++ b/src/app/models/dashboard-statistics.ts
@@ -0,0 +1,47 @@
+export interface ProtocolStatistics {
+  name: string;
+  total_packets: number;
+  total_bytes: number;
+}
+
+export interface ProtocolStatisticsDto {
+  name: string;
+  'total-packets': number;
+  'total-bytes': number;
+}
+
+export interface InformationRate {
+  min: number;
+  max: number;
+  current: number;
+}
+
+export interface DashboardStatisticsDto {
+  'total-time': number;
+  protocols: ProtocolStatisticsDto[];
+  'information-rate': InformationRate;
+}
+
+export interface DashboardStatistics {
+  total_time: Date;
+  protocols: ProtocolStatistics[];
+  information_rate: InformationRate;
+}
+
+export function dtoToDashboardStatistics(
+  dto: DashboardStatisticsDto
+): DashboardStatistics {
+  return {
+    total_time: new Date(dto['total-time'] * 1000),
+    protocols: dto.protocols.map((protocol: ProtocolStatisticsDto) => ({
+      name: protocol.name,
+      total_packets: protocol['total-packets'],
+      total_bytes: protocol['total-bytes'],
+    })),
+    information_rate: {
+      min: dto['information-rate'].min,
+      max: dto['information-rate'].max,
+      current: dto['information-rate'].current,
+    },
+  };
+}
diff --git a/src/app/pipes/decimal.pipe.ts b/src/app/pipes/decimal.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8311eabce33825a94a7fae095311bd91c3beb30f
--- /dev/null
+++ b/src/app/pipes/decimal.pipe.ts
@@ -0,0 +1,16 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+  name: 'decimal',
+})
+export class DecimalPipe implements PipeTransform {
+  transform(value: number | string, decimalPlaces: number = 2): string {
+    if (value == null || isNaN(Number(value))) {
+      return '';
+    }
+
+    return Number(value).toLocaleString('pl-PL', {
+      maximumFractionDigits: decimalPlaces,
+    });
+  }
+}
diff --git a/src/app/pipes/time.pipe.ts b/src/app/pipes/time.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3213400b643d473c4d78b29282cb866ca4ffd76a
--- /dev/null
+++ b/src/app/pipes/time.pipe.ts
@@ -0,0 +1,15 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+  name: 'time',
+})
+export class TimePipe implements PipeTransform {
+  transform(date: Date): string {
+    let totalSeconds = Math.floor(date.getTime() / 1000);
+    const hours = Math.floor(totalSeconds / 3600);
+    totalSeconds %= 3600;
+    const minutes = Math.floor(totalSeconds / 60);
+    const seconds = totalSeconds % 60;
+    return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
+  }
+}