diff --git a/main.go b/main.go
index 7e8099a447f7a779398c03b0049175744d8920b0..9b0fc7beca86ba050a95a239f365f11630b5cba6 100644
--- a/main.go
+++ b/main.go
@@ -7,12 +7,13 @@ import (
 	"github.com/iotaledger/goshimmer/plugins/cli"
 	"github.com/iotaledger/goshimmer/plugins/gossip"
 	"github.com/iotaledger/goshimmer/plugins/gracefulshutdown"
-	"github.com/iotaledger/goshimmer/plugins/spammer"
 	"github.com/iotaledger/goshimmer/plugins/statusscreen"
+	statusscreen_tps "github.com/iotaledger/goshimmer/plugins/statusscreen-tps"
 	"github.com/iotaledger/goshimmer/plugins/tangle"
 	"github.com/iotaledger/goshimmer/plugins/tipselection"
 	"github.com/iotaledger/goshimmer/plugins/webapi"
 	webapi_gtta "github.com/iotaledger/goshimmer/plugins/webapi-gtta"
+	webapi_spammer "github.com/iotaledger/goshimmer/plugins/webapi-spammer"
 )
 
 func main() {
@@ -22,12 +23,14 @@ func main() {
 		gossip.PLUGIN,
 		tangle.PLUGIN,
 		analysis.PLUGIN,
-		statusscreen.PLUGIN,
 		gracefulshutdown.PLUGIN,
 		tipselection.PLUGIN,
-		spammer.PLUGIN,
+
+		statusscreen.PLUGIN,
+		statusscreen_tps.PLUGIN,
 
 		webapi.PLUGIN,
 		webapi_gtta.PLUGIN,
+		webapi_spammer.PLUGIN,
 	)
 }
diff --git a/packages/transactionspammer/transactionspammer.go b/packages/transactionspammer/transactionspammer.go
new file mode 100644
index 0000000000000000000000000000000000000000..503a0f5af72c6f3120b0749ebb30bf5778ba3cd5
--- /dev/null
+++ b/packages/transactionspammer/transactionspammer.go
@@ -0,0 +1,83 @@
+package transactionspammer
+
+import (
+	"sync"
+	"time"
+
+	"github.com/iotaledger/goshimmer/packages/daemon"
+	"github.com/iotaledger/goshimmer/packages/model/value_transaction"
+	"github.com/iotaledger/goshimmer/plugins/gossip"
+	"github.com/iotaledger/goshimmer/plugins/tipselection"
+)
+
+var spamming = false
+
+var startMutex sync.Mutex
+
+var shutdownSignal chan int
+
+func Start(tps int64) {
+	startMutex.Lock()
+
+	if !spamming {
+		shutdownSignal = make(chan int, 1)
+
+		func(shutdownSignal chan int) {
+			daemon.BackgroundWorker(func() {
+				for {
+					start := time.Now()
+					sentCounter := int64(0)
+					totalSentCounter := int64(0)
+
+					for {
+						select {
+						case <-daemon.ShutdownSignal:
+							return
+
+						case <-shutdownSignal:
+							return
+
+						default:
+							sentCounter++
+							totalSentCounter++
+
+							tx := value_transaction.New()
+							tx.SetValue(totalSentCounter)
+							tx.SetBranchTransactionHash(tipselection.GetRandomTip())
+							tx.SetTrunkTransactionHash(tipselection.GetRandomTip())
+
+							gossip.Events.ReceiveTransaction.Trigger(tx.MetaTransaction)
+
+							if sentCounter >= tps {
+								duration := time.Since(start)
+								if duration < time.Second {
+									time.Sleep(time.Second - duration)
+
+									start = time.Now()
+								}
+
+								sentCounter = 0
+							}
+						}
+					}
+				}
+			})
+		}(shutdownSignal)
+
+		spamming = true
+	}
+
+	startMutex.Unlock()
+}
+
+func Stop() {
+	startMutex.Lock()
+
+	if spamming {
+		close(shutdownSignal)
+
+		spamming = false
+	}
+
+	startMutex.Unlock()
+}
diff --git a/plugins/spammer/spammer.go b/plugins/spammer/spammer.go
deleted file mode 100644
index 44985dea31b0032028a941c71b4d621ad8db4b51..0000000000000000000000000000000000000000
--- a/plugins/spammer/spammer.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package spammer
-
-import (
-	"fmt"
-	"runtime"
-	"strconv"
-	"sync/atomic"
-	"time"
-
-	"github.com/iotaledger/goshimmer/packages/daemon"
-	"github.com/iotaledger/goshimmer/packages/events"
-	"github.com/iotaledger/goshimmer/packages/model/meta_transaction"
-	"github.com/iotaledger/goshimmer/packages/model/value_transaction"
-	"github.com/iotaledger/goshimmer/packages/node"
-	"github.com/iotaledger/goshimmer/plugins/gossip"
-	"github.com/iotaledger/goshimmer/plugins/tangle"
-	"github.com/iotaledger/goshimmer/plugins/tipselection"
-)
-
-var PLUGIN = node.NewPlugin("Spammer", configure, run)
-
-func bToMb(b uint64) uint64 {
-	return b / 1024 / 1024
-}
-
-func configure(plugin *node.Plugin) {
-	tpsCounter := 0
-	solidCounter := 0
-	var receivedCounter uint64
-
-	gossip.Events.ReceiveTransaction.Attach(events.NewClosure(func(transaction *meta_transaction.MetaTransaction) {
-		atomic.AddUint64(&receivedCounter, 1)
-	}))
-
-	go func() {
-		for {
-			select {
-			case <-daemon.ShutdownSignal:
-				return
-
-			case <-time.After(1 * time.Second):
-				fmt.Println("RECEIVED", receivedCounter, " / TPS "+strconv.Itoa(tpsCounter)+" / SOLID "+strconv.Itoa(solidCounter), " / TIPS ", tipselection.GetTipsCount())
-				fmt.Println(runtime.NumGoroutine())
-
-				var m runtime.MemStats
-				runtime.ReadMemStats(&m)
-				// For info on each, see: https://golang.org/pkg/runtime/#MemStats
-				fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc))
-				fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc))
-				fmt.Printf("\tSys = %v MiB", bToMb(m.Sys))
-				fmt.Printf("\tNumGC = %v\n", m.NumGC)
-
-				tpsCounter = 0
-			}
-		}
-	}()
-
-	tangle.Events.TransactionSolid.Attach(events.NewClosure(func(transaction *value_transaction.ValueTransaction) {
-		solidCounter++
-		tpsCounter++
-	}))
-}
-
-func run(plugin *node.Plugin) {
-	daemon.BackgroundWorker(func() {
-		for {
-			transactionCount := 100000
-
-			for i := 0; i < transactionCount; i++ {
-				select {
-				case <-daemon.ShutdownSignal:
-					return
-				default:
-					tx := value_transaction.New()
-					tx.SetValue(int64(i + 1))
-					tx.SetBranchTransactionHash(tipselection.GetRandomTip())
-					tx.SetTrunkTransactionHash(tipselection.GetRandomTip())
-
-					gossip.Events.ReceiveTransaction.Trigger(tx.MetaTransaction)
-				}
-			}
-
-			//time.Sleep(5 * time.Second)
-		}
-	})
-}
diff --git a/plugins/statusscreen-tps/plugin.go b/plugins/statusscreen-tps/plugin.go
new file mode 100644
index 0000000000000000000000000000000000000000..eabb868f15e786ecea795ceac8173f2984d4a31c
--- /dev/null
+++ b/plugins/statusscreen-tps/plugin.go
@@ -0,0 +1,56 @@
+package statusscreen_tps
+
+import (
+	"strconv"
+	"sync/atomic"
+	"time"
+
+	"github.com/iotaledger/goshimmer/packages/daemon"
+	"github.com/iotaledger/goshimmer/packages/events"
+	"github.com/iotaledger/goshimmer/packages/model/meta_transaction"
+	"github.com/iotaledger/goshimmer/packages/model/value_transaction"
+	"github.com/iotaledger/goshimmer/packages/node"
+	"github.com/iotaledger/goshimmer/plugins/gossip"
+	"github.com/iotaledger/goshimmer/plugins/statusscreen"
+	"github.com/iotaledger/goshimmer/plugins/tangle"
+)
+
+var receivedTpsCounter uint64
+
+var solidTpsCounter uint64
+
+var receivedTps uint64
+
+var solidTps uint64
+
+var PLUGIN = node.NewPlugin("Statusscreen TPS", func(plugin *node.Plugin) {
+	gossip.Events.ReceiveTransaction.Attach(events.NewClosure(func(_ *meta_transaction.MetaTransaction) {
+		atomic.AddUint64(&receivedTpsCounter, 1)
+	}))
+
+	tangle.Events.TransactionSolid.Attach(events.NewClosure(func(_ *value_transaction.ValueTransaction) {
+		atomic.AddUint64(&solidTpsCounter, 1)
+	}))
+
+	statusscreen.AddHeaderInfo(func() (s string, s2 string) {
+		return "TPS", strconv.FormatUint(atomic.LoadUint64(&receivedTps), 10) + " received / " + strconv.FormatUint(atomic.LoadUint64(&solidTps), 10) + " new"
+	})
+}, func(plugin *node.Plugin) {
+	daemon.BackgroundWorker(func() {
+		ticker := time.NewTicker(time.Second)
+
+		for {
+			select {
+			case <-daemon.ShutdownSignal:
+				return
+
+			case <-ticker.C:
+				atomic.StoreUint64(&receivedTps, atomic.LoadUint64(&receivedTpsCounter))
+				atomic.StoreUint64(&solidTps, atomic.LoadUint64(&solidTpsCounter))
+
+				atomic.StoreUint64(&receivedTpsCounter, 0)
+				atomic.StoreUint64(&solidTpsCounter, 0)
+			}
+		}
+	})
+})
diff --git a/plugins/statusscreen/ui_header_bar.go b/plugins/statusscreen/ui_header_bar.go
index 4089d415078ee8f7b02b3a5bd289dbb9f1411ca3..5d7a3993586341c8d2dbb8c481621bab94029aaa 100644
--- a/plugins/statusscreen/ui_header_bar.go
+++ b/plugins/statusscreen/ui_header_bar.go
@@ -17,6 +17,12 @@ import (
 
 var start = time.Now()
 
+var headerInfos = make([]func() (string, string), 0)
+
+func AddHeaderInfo(generator func() (string, string)) {
+	headerInfos = append(headerInfos, generator)
+}
+
 type UIHeaderBar struct {
 	Primitive     *tview.Grid
 	LogoContainer *tview.TextView
@@ -62,9 +68,16 @@ func (headerBar *UIHeaderBar) Update() {
 
 	fmt.Fprintln(headerBar.InfoContainer)
 	fmt.Fprintln(headerBar.InfoContainer, "[::d]COO-LESS IOTA PROTOTYPE  -  [::b]Status: [green::b]SYNCED  ")
-	fmt.Fprintln(headerBar.InfoContainer)
-	fmt.Fprintln(headerBar.InfoContainer)
-	fmt.Fprintln(headerBar.InfoContainer)
+	for i := 0; i < 3-len(headerInfos); i++ {
+		fmt.Fprintln(headerBar.InfoContainer)
+	}
+
+	for _, infoGenerator := range headerInfos {
+		fieldName, fieldValue := infoGenerator()
+		fmt.Fprintf(headerBar.InfoContainer, "[::b]%v: [::d]%40v  ", fieldName, fieldValue)
+		fmt.Fprintln(headerBar.InfoContainer)
+	}
+
 	fmt.Fprintf(headerBar.InfoContainer, "[::b]Node ID: [::d]%40v  ", accountability.OwnId().StringIdentifier)
 	fmt.Fprintln(headerBar.InfoContainer)
 	fmt.Fprintf(headerBar.InfoContainer, "[::b]Neighbors: [::d]%40v  ", strconv.Itoa(len(chosenneighbors.INSTANCE.Peers))+" chosen / "+strconv.Itoa(len(acceptedneighbors.INSTANCE.Peers))+" accepted")
diff --git a/plugins/webapi-gtta/plugin.go b/plugins/webapi-gtta/plugin.go
index b174e7ec57650af8a2d4b89cc3da7cd164c7c6fa..3a97085736a984f78ea8df9528ba8d53b68d9721 100644
--- a/plugins/webapi-gtta/plugin.go
+++ b/plugins/webapi-gtta/plugin.go
@@ -21,14 +21,14 @@ func Handler(c echo.Context) error {
 	branchTransactionHash := tipselection.GetRandomTip()
 	trunkTransactionHash := tipselection.GetRandomTip()
 
-	return c.JSON(http.StatusOK, response{
+	return c.JSON(http.StatusOK, webResponse{
 		Duration:          time.Since(start).Nanoseconds() / 1e6,
 		BranchTransaction: branchTransactionHash,
 		TrunkTransaction:  trunkTransactionHash,
 	})
 }
 
-type response struct {
+type webResponse struct {
 	Duration          int64           `json:"duration"`
 	BranchTransaction ternary.Trinary `json:"branchTransaction"`
 	TrunkTransaction  ternary.Trinary `json:"trunkTransaction"`
diff --git a/plugins/webapi-spammer/plugin.go b/plugins/webapi-spammer/plugin.go
new file mode 100644
index 0000000000000000000000000000000000000000..b216aca5e0f9d3e905eb30b898b6066f4dd42c72
--- /dev/null
+++ b/plugins/webapi-spammer/plugin.go
@@ -0,0 +1,73 @@
+package webapi_spammer
+
+import (
+	"net/http"
+	"time"
+
+	"github.com/iotaledger/goshimmer/packages/node"
+	"github.com/iotaledger/goshimmer/packages/transactionspammer"
+	"github.com/iotaledger/goshimmer/plugins/webapi"
+	"github.com/labstack/echo"
+)
+
+var PLUGIN = node.NewPlugin("Spammer", configure)
+
+func configure(plugin *node.Plugin) {
+	webapi.AddEndpoint("spammer", WebApiHandler)
+}
+
+func WebApiHandler(c echo.Context) error {
+	c.Set("requestStartTime", time.Now())
+
+	var request webRequest
+	if err := c.Bind(&request); err != nil {
+		return requestFailed(c, err.Error())
+	}
+
+	switch request.Cmd {
+	case "start":
+		if request.Tps == 0 {
+			request.Tps = 1000
+		}
+
+		transactionspammer.Stop()
+		transactionspammer.Start(request.Tps)
+
+		return requestSuccessful(c, "started spamming transactions")
+
+	case "stop":
+		transactionspammer.Stop()
+
+		return requestSuccessful(c, "stopped spamming transactions")
+
+	default:
+		return requestFailed(c, "invalid cmd in request")
+	}
+}
+
+func requestSuccessful(c echo.Context, message string) error {
+	return c.JSON(http.StatusOK, webResponse{
+		Duration: time.Since(c.Get("requestStartTime").(time.Time)).Nanoseconds() / 1e6,
+		Status:   "success",
+		Message:  message,
+	})
+}
+
+func requestFailed(c echo.Context, message string) error {
+	return c.JSON(http.StatusOK, webResponse{
+		Duration: time.Since(c.Get("requestStartTime").(time.Time)).Nanoseconds() / 1e6,
+		Status:   "failed",
+		Message:  message,
+	})
+}
+
+type webResponse struct {
+	Duration int64  `json:"duration"`
+	Status   string `json:"status"`
+	Message  string `json:"message"`
+}
+
+type webRequest struct {
+	Cmd string `json:"cmd"`
+	Tps int64  `json:"tps"`
+}