diff --git a/README.md b/README.md
index 35143b0af6ff2fa07d73f14cb46972657faad171..5d003f515f927e656b454c9e8229c396784f0b4d 100644
--- a/README.md
+++ b/README.md
@@ -24,11 +24,11 @@ the name of your go project in `go.mod` (don't need to do this step unless you w
 First off you will need to install benchstat for go. Then you
 can do the following:
 1. Write the benchmark test in a file, and run the command
-2. `go test -bench=<BenchmarkFunctionName> -benchmem -count 5 -run=^# | tee old.txt ./...` for
+2. `go test -bench=<BenchmarkFunctionName> -benchmem -count 5 -run=^#  ./... | tee performance/old.txt` for
 your old implementation, and 
-`go test -bench=<BenchmarkFunctionName> -benchmem -count 5 -run=^# | tee new.txt ./...` for your new implementation where only the implementation called in the
+`go test -bench=<BenchmarkFunctionName> -benchmem -count 5 -run=^# ./... | tee performance/new.txt ` for your new implementation where only the implementation called in the
 benchmark is changed.
-3. run `/path/to/benchstat path/to/old.txt path/to/new.txt` (running this command from the
+3. run `/path/to/benchstat performance/old.txt performance/new.txt > performance/last-diff.txt` (running this command from the
 main repo path), and you have a decreasing delta on the new version,
 you are doing better than in performance than the old version for
 (speed, memory etc.)
diff --git a/performance/last-diff.txt b/performance/last-diff.txt
new file mode 100644
index 0000000000000000000000000000000000000000..51a52d8262c6ca9efc4bc9f4fd59442d60ca3f00
--- /dev/null
+++ b/performance/last-diff.txt
@@ -0,0 +1,8 @@
+name                                            old time/op    new time/op    delta
+Collect/it_should_collect_jira_related_data-12    4.76ms ± 5%    4.72ms ± 7%    ~     (p=1.000 n=5+5)
+
+name                                            old alloc/op   new alloc/op   delta
+Collect/it_should_collect_jira_related_data-12    12.7MB ±11%    12.9MB ± 9%    ~     (p=0.690 n=5+5)
+
+name                                            old allocs/op  new allocs/op  delta
+Collect/it_should_collect_jira_related_data-12     4.22k ± 0%     4.11k ± 0%  -2.71%  (p=0.029 n=4+4)
diff --git a/performance/new.txt b/performance/new.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f57eebba43ec5f41d364379ae70d3dd6c7f0b73c
--- /dev/null
+++ b/performance/new.txt
@@ -0,0 +1,81 @@
+PASS
+ok  	holocron/collector-jira-workflow/cmd	0.011s
+PASS
+ok  	holocron/collector-jira-workflow/config	0.010s
+goos: darwin
+goarch: amd64
+pkg: holocron/collector-jira-workflow/pkg/collector
+cpu: Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz
+BenchmarkCollect/it_should_collect_jira_related_data-12         	     632	   4752403 ns/op	12506353 B/op	    4123 allocs/op
+--- BENCH: BenchmarkCollect/it_should_collect_jira_related_data-12
+    main_test.go:205: PASS:	GetBoards()
+    main_test.go:205: PASS:	DeleteBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetActiveBoards()
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetTickets(mock.argumentMatcher)
+    main_test.go:205: PASS:	DeleteTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+	... [output truncated]
+BenchmarkCollect/it_should_collect_jira_related_data-12         	     632	   4510787 ns/op	12475593 B/op	    4108 allocs/op
+--- BENCH: BenchmarkCollect/it_should_collect_jira_related_data-12
+    main_test.go:205: PASS:	GetBoards()
+    main_test.go:205: PASS:	DeleteBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetActiveBoards()
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetTickets(mock.argumentMatcher)
+    main_test.go:205: PASS:	DeleteTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+	... [output truncated]
+BenchmarkCollect/it_should_collect_jira_related_data-12         	     709	   4977852 ns/op	13939821 B/op	    4109 allocs/op
+--- BENCH: BenchmarkCollect/it_should_collect_jira_related_data-12
+    main_test.go:205: PASS:	GetBoards()
+    main_test.go:205: PASS:	DeleteBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetActiveBoards()
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetTickets(mock.argumentMatcher)
+    main_test.go:205: PASS:	DeleteTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+	... [output truncated]
+BenchmarkCollect/it_should_collect_jira_related_data-12         	     708	   4987159 ns/op	13922303 B/op	    4110 allocs/op
+--- BENCH: BenchmarkCollect/it_should_collect_jira_related_data-12
+    main_test.go:205: PASS:	GetBoards()
+    main_test.go:205: PASS:	DeleteBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetActiveBoards()
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetTickets(mock.argumentMatcher)
+    main_test.go:205: PASS:	DeleteTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+	... [output truncated]
+BenchmarkCollect/it_should_collect_jira_related_data-12         	     597	   4365503 ns/op	11816312 B/op	    4110 allocs/op
+--- BENCH: BenchmarkCollect/it_should_collect_jira_related_data-12
+    main_test.go:205: PASS:	GetBoards()
+    main_test.go:205: PASS:	DeleteBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetActiveBoards()
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetTickets(mock.argumentMatcher)
+    main_test.go:205: PASS:	DeleteTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+	... [output truncated]
+PASS
+ok  	holocron/collector-jira-workflow/pkg/collector	16.484s
+PASS
+ok  	holocron/collector-jira-workflow/pkg/database	0.012s
+PASS
+ok  	holocron/collector-jira-workflow/pkg/httpClient	0.012s
+PASS
+ok  	holocron/collector-jira-workflow/pkg/utils	0.010s
diff --git a/performance/old.txt b/performance/old.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f600a6c0568a13e67cacf386046b6cd89c4a02cd
--- /dev/null
+++ b/performance/old.txt
@@ -0,0 +1,81 @@
+PASS
+ok  	holocron/collector-jira-workflow/cmd	0.011s
+PASS
+ok  	holocron/collector-jira-workflow/config	0.011s
+goos: darwin
+goarch: amd64
+pkg: holocron/collector-jira-workflow/pkg/collector
+cpu: Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz
+BenchmarkCollect/it_should_collect_jira_related_data-12         	     571	   4507704 ns/op	11354847 B/op	    4235 allocs/op
+--- BENCH: BenchmarkCollect/it_should_collect_jira_related_data-12
+    main_test.go:205: PASS:	GetBoards()
+    main_test.go:205: PASS:	DeleteBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetActiveBoards()
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetTickets(mock.argumentMatcher)
+    main_test.go:205: PASS:	DeleteTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+	... [output truncated]
+BenchmarkCollect/it_should_collect_jira_related_data-12         	     685	   4916627 ns/op	13496644 B/op	    4224 allocs/op
+--- BENCH: BenchmarkCollect/it_should_collect_jira_related_data-12
+    main_test.go:205: PASS:	GetBoards()
+    main_test.go:205: PASS:	DeleteBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetActiveBoards()
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetTickets(mock.argumentMatcher)
+    main_test.go:205: PASS:	DeleteTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+	... [output truncated]
+BenchmarkCollect/it_should_collect_jira_related_data-12         	     685	   4917054 ns/op	13491501 B/op	    4223 allocs/op
+--- BENCH: BenchmarkCollect/it_should_collect_jira_related_data-12
+    main_test.go:205: PASS:	GetBoards()
+    main_test.go:205: PASS:	DeleteBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetActiveBoards()
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetTickets(mock.argumentMatcher)
+    main_test.go:205: PASS:	DeleteTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+	... [output truncated]
+BenchmarkCollect/it_should_collect_jira_related_data-12         	     608	   4513139 ns/op	12032696 B/op	    4223 allocs/op
+--- BENCH: BenchmarkCollect/it_should_collect_jira_related_data-12
+    main_test.go:205: PASS:	GetBoards()
+    main_test.go:205: PASS:	DeleteBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetActiveBoards()
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetTickets(mock.argumentMatcher)
+    main_test.go:205: PASS:	DeleteTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+	... [output truncated]
+BenchmarkCollect/it_should_collect_jira_related_data-12         	     674	   4930024 ns/op	13285131 B/op	    4224 allocs/op
+--- BENCH: BenchmarkCollect/it_should_collect_jira_related_data-12
+    main_test.go:205: PASS:	GetBoards()
+    main_test.go:205: PASS:	DeleteBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetActiveBoards()
+    main_test.go:205: PASS:	UpsertBoard(mock.argumentMatcher)
+    main_test.go:205: PASS:	GetTickets(mock.argumentMatcher)
+    main_test.go:205: PASS:	DeleteTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+    main_test.go:205: PASS:	UpsertTicket(mock.argumentMatcher)
+	... [output truncated]
+PASS
+ok  	holocron/collector-jira-workflow/pkg/collector	16.355s
+PASS
+ok  	holocron/collector-jira-workflow/pkg/database	0.013s
+PASS
+ok  	holocron/collector-jira-workflow/pkg/httpClient	0.013s
+PASS
+ok  	holocron/collector-jira-workflow/pkg/utils	0.015s
diff --git a/pkg/collector/collectBoards.go b/pkg/collector/collectBoards.go
index 807a4b8d62b0f790fc22f722c2efc5c528dc590a..6820e78df54bea323a8ac63d3f1fb76339ce7b9e 100644
--- a/pkg/collector/collectBoards.go
+++ b/pkg/collector/collectBoards.go
@@ -1,27 +1,32 @@
 package collector
 
 import (
-	"fmt"
 	"time"
 
-	"holocron/collector-jira-workflow/config"
 	"holocron/collector-jira-workflow/pkg/database"
 	"holocron/collector-jira-workflow/pkg/httpClient"
+	"holocron/collector-jira-workflow/pkg/utils"
 )
 
-func collectBoards(db database.DB) *[]database.BoardJSON {
-	currentTime := time.Now()
-	boards := httpClient.GetBoards()
-	for i, b := range *boards {
-		(*boards)[i].API_URL = fmt.Sprintf("%s/board/%d", config.API_URL, b.ID)
-		(*boards)[i].LastCollected = currentTime
+func saveBoards(boards *[]database.BoardJSON, db database.DB) {
+	utils.Logger.Info("Saving boards...")
+	for _, board := range *boards {
+		db.UpsertBoard(board)
 	}
-	pruneBoards(boards, db)
+}
+
+func setLastUpdated(activeBoards []database.CollectorTarget, time time.Time,
+	db database.DB) {
 
-	return boards
+	for _, board := range activeBoards {
+		currentBoard := board.ToBoardJSON()
+		currentBoard.LastCollected = time
+		db.UpsertBoard(currentBoard)
+	}
 }
 
-func pruneBoards(collectedBoards *[]database.BoardJSON, db database.DB) {
+func pruneBoards(collectedBoards *[]database.BoardJSON, db database.DB) (delCount int) {
+	utils.Logger.Info("Deleting boards...")
 	savedBoards := db.GetBoards()
 	var collectedHashTable map[uint]bool = make(map[uint]bool, len(*collectedBoards))
 	for _, board := range *collectedBoards {
@@ -30,6 +35,25 @@ func pruneBoards(collectedBoards *[]database.BoardJSON, db database.DB) {
 	for _, board := range savedBoards {
 		if _, boardInAPIResp := collectedHashTable[board.BoardId]; !boardInAPIResp {
 			db.DeleteBoard(board)
+			delCount++
 		}
 	}
+
+	return delCount
+}
+
+func collectBoards(db database.DB) {
+	utils.Logger.Info("Collecting boards...")
+	startTime := time.Now()
+	boards := httpClient.GetBoards()
+	delCount := pruneBoards(boards, db)
+	saveBoards(boards, db)
+
+	statsFormattedStr := "\n---Finished collecting boards---\n" +
+		"---Time Elapsed - %.0f seconds---\n" +
+		"%d\t-\tBoards Collected\n" +
+		"%d\t-\tBoards Removed\n"
+	utils.Logger.Infof(statsFormattedStr,
+		time.Since(startTime).Seconds(),
+		len(*boards), delCount)
 }
diff --git a/pkg/collector/collectBoards_test.go b/pkg/collector/collectBoards_test.go
index 98773bf3c23a92db3e168dfd4f9930b6f89eeac5..b5d8da1d4f13a3bc6337ef9917974518c23a06ea 100644
--- a/pkg/collector/collectBoards_test.go
+++ b/pkg/collector/collectBoards_test.go
@@ -1,6 +1,7 @@
 package collector
 
 import (
+	"bytes"
 	"net/http"
 	"net/http/httptest"
 	"testing"
@@ -8,10 +9,12 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
 
+	"holocron/collector-jira-workflow/pkg/database"
 	db "holocron/collector-jira-workflow/pkg/database"
+	"holocron/collector-jira-workflow/pkg/utils"
 )
 
-//nolint: funlen // This is just a test.
+//nolint: funlen, gocyclo // This is just a test.
 func TestCollectBoards(t *testing.T) {
 	var testCases = []struct {
 		AddAPIMocks        func(*mockAPI)
@@ -33,18 +36,22 @@ func TestCollectBoards(t *testing.T) {
 				mdb.T().Helper()
 
 				mdb.On("GetBoards").Return([]db.CollectorTarget{}).Once()
+
+				mdb.On("UpsertBoard", mock.MatchedBy(func(b database.BoardJSON) bool {
+					return b.ID == uint(1) && b.Name == "test1" && b.URL == "test.com/1"
+				})).Once()
 			},
 			AssertExpectations: func(mdb *mockDB, api *mockAPI, _ *httptest.Server) {
 				defer func() {
 					mdb.AssertExpectations(mdb.T())
 					api.AssertExpectations(api.T())
 				}()
-				result := *collectBoards(mdb)
-
-				assert.Equal(mdb.T(), 1, len(result))
-				assert.Equal(mdb.T(), uint(1), result[0].ID)
-				assert.Equal(mdb.T(), "test1", result[0].Name)
-				assert.Equal(mdb.T(), "test.com/1", result[0].URL)
+				// setting output recorder
+				buffer := bytes.Buffer{}
+				utils.Logger.InfoLogger.SetOutput(&buffer)
+				// testing
+				collectBoards(mdb)
+				assert.Contains(mdb.T(), buffer.String(), "1\t-\tBoards Collected")
 			},
 		},
 		{
@@ -63,24 +70,30 @@ func TestCollectBoards(t *testing.T) {
 				getMock("testdata/db/collector_targets/boards-to-delete.json",
 					mdb.T(), &boardsToDelete)
 				mdb.On("GetBoards").Return(boardsToDelete).Once()
+
 				for _, board := range boardsToDelete {
 					board := board
 					mdb.On("DeleteBoard", mock.MatchedBy(func(b db.CollectorTarget) bool {
 						return b.Name == board.Name
 					})).Once()
 				}
+
+				mdb.On("UpsertBoard", mock.MatchedBy(func(b database.BoardJSON) bool {
+					return b.ID == uint(5) && b.Name == "test" && b.URL == "test.com"
+				})).Once()
 			},
 			AssertExpectations: func(mdb *mockDB, api *mockAPI, _ *httptest.Server) {
 				defer func() {
 					mdb.AssertExpectations(mdb.T())
 					api.AssertExpectations(api.T())
 				}()
-				result := *collectBoards(mdb)
-
-				assert.Equal(mdb.T(), 1, len(result))
-				assert.Equal(mdb.T(), uint(5), result[0].ID)
-				assert.Equal(mdb.T(), "test", result[0].Name)
-				assert.Equal(mdb.T(), "test.com", result[0].URL)
+				// setting output recorder
+				buffer := bytes.Buffer{}
+				utils.Logger.InfoLogger.SetOutput(&buffer)
+				// testing
+				collectBoards(mdb)
+				assert.Contains(mdb.T(), buffer.String(), "1\t-\tBoards Collected")
+				assert.Contains(mdb.T(), buffer.String(), "1\t-\tBoards Removed")
 			},
 		},
 	}
diff --git a/pkg/collector/collectTickets.go b/pkg/collector/collectTickets.go
index 209dc2b4ea594abdefc0a7e3b2a97df05c1a9e9b..c20c38cfc92fb6e12a4dbb340bbaee56de041c5e 100644
--- a/pkg/collector/collectTickets.go
+++ b/pkg/collector/collectTickets.go
@@ -1,43 +1,25 @@
 package collector
 
 import (
+	"sync"
+	"time"
+
 	"holocron/collector-jira-workflow/pkg/database"
 	"holocron/collector-jira-workflow/pkg/httpClient"
+	"holocron/collector-jira-workflow/pkg/utils"
 )
 
-func collectTickets(
-	boards []database.CollectorTarget, db database.DB, ch chan *[]database.TicketJSON,
-) {
-
-	ticketChannels := make(chan *[]database.TicketJSON, len(boards))
-	for _, board := range boards {
-		go collectTicketsForBoard(board, db, ticketChannels)
-	}
-	result := &[]database.TicketJSON{}
-	for range boards {
-		*result = append(*result, *<-ticketChannels...)
-	}
-	ch <- result
-}
-
-func collectTicketsForBoard(
-	board database.CollectorTarget, db database.DB, ch chan *[]database.TicketJSON,
-) {
-
-	tickets := httpClient.GetTickets(board)
-	pruneTickets(tickets, board, db)
-	for i := range *tickets {
-		(*tickets)[i].BoardId = board.ID
-		(*tickets)[i].BuildStatusHistory()
+func saveTickets(tickets []database.TicketJSON, db database.DB) {
+	for _, ticket := range tickets {
+		db.UpsertTicket(ticket)
 	}
-	ch <- tickets
 }
 
 func pruneTickets(
 	collectedTickets *[]database.TicketJSON,
 	board database.CollectorTarget,
 	db database.DB,
-) {
+) (delCount int) {
 
 	savedTickets := db.GetTickets(board)
 	var collectedHashTable map[string]bool = make(map[string]bool, len(*collectedTickets))
@@ -47,6 +29,45 @@ func pruneTickets(
 	for _, ticket := range savedTickets {
 		if _, ticketInAPIResp := collectedHashTable[ticket.TicketID]; !ticketInAPIResp {
 			db.DeleteTicket(ticket)
+			delCount++
 		}
 	}
+
+	return delCount
+}
+
+func collectTickets(activeBoards []database.CollectorTarget, db database.DB) {
+	utils.Logger.Info("Collecting workflow data...")
+	var (
+		mtx       sync.Mutex
+		wg        sync.WaitGroup
+		delCount  = 0
+		saveCount = 0
+		startTime = time.Now()
+	)
+	wg.Add(len(activeBoards))
+	for _, board := range activeBoards {
+		go func(board database.CollectorTarget) {
+			// let the fetching happen concurrently
+			defer wg.Done()
+			ticketsForBoard := httpClient.GetTickets(board)
+			// but only one go routine can write to db, and count variables
+			// at a time
+			mtx.Lock()
+			defer mtx.Unlock()
+			deleted := pruneTickets(ticketsForBoard, board, db)
+			saveTickets(*ticketsForBoard, db)
+			saveCount += len(*ticketsForBoard)
+			delCount += deleted
+		}(board)
+	}
+	wg.Wait()
+
+	statsFormattedStr := "\n---Finished collecting tickets---\n" +
+		"---Time Elapsed - %.0f seconds---\n" +
+		"%d\t-\tTickets Collected\n" +
+		"%d\t-\tTickets Removed\n"
+	utils.Logger.Infof(statsFormattedStr,
+		time.Since(startTime).Seconds(),
+		saveCount, delCount)
 }
diff --git a/pkg/collector/collectTickets_test.go b/pkg/collector/collectTickets_test.go
index 8573ee3b8fe638b9fef52b69ab4df3353bf39cfb..9fba3d6d9559d0fa177cfb8063c930f1fbbea026 100644
--- a/pkg/collector/collectTickets_test.go
+++ b/pkg/collector/collectTickets_test.go
@@ -1,6 +1,7 @@
 package collector
 
 import (
+	"bytes"
 	"net/http"
 	"net/http/httptest"
 	"testing"
@@ -9,9 +10,10 @@ import (
 	"github.com/stretchr/testify/mock"
 
 	db "holocron/collector-jira-workflow/pkg/database"
+	"holocron/collector-jira-workflow/pkg/utils"
 )
 
-//nolint: funlen // This is just a test.
+//nolint: funlen, gocyclo // This is just a test.
 func TestCollectTickets(t *testing.T) {
 	var testCases = []struct {
 		AddAPIMocks        func(*mockAPI)
@@ -39,6 +41,12 @@ func TestCollectTickets(t *testing.T) {
 				mdb.On("GetTickets", mock.MatchedBy(func(b db.CollectorTarget) bool {
 					return b.Name == activeBoards[0].Name
 				})).Return([]db.Ticket{})
+
+				mdb.On("UpsertTicket", mock.MatchedBy(func(t db.TicketJSON) bool {
+					return t.ID == "1" && t.Fields.Status.Name == "testStatus1" &&
+						t.Fields.Assignee.Email == "testEmail1" &&
+						t.Fields.Type.Name == "testType1"
+				})).Once()
 			},
 			//nolint:dupl // This is just a test.
 			AssertExpectations: func(mdb *mockDB, api *mockAPI, s *httptest.Server) {
@@ -46,19 +54,17 @@ func TestCollectTickets(t *testing.T) {
 					mdb.AssertExpectations(mdb.T())
 					api.AssertExpectations(api.T())
 				}()
+				// saving logs
+				buffer := bytes.Buffer{}
+				utils.Logger.InfoLogger.SetOutput(&buffer)
+				// testing
 				var boards []db.CollectorTarget
 				getMock("testdata/db/collector_targets/collector-targets.json", mdb.T(), &boards)
 				var activeBoards = []db.CollectorTarget{boards[0]}
 				activeBoards[0].API_URL = s.URL
-				resultChannel := make(chan *[]db.TicketJSON)
-				go collectTickets(activeBoards, mdb, resultChannel)
-				result := *<-resultChannel
+				collectTickets(activeBoards, mdb)
 
-				assert.Equal(mdb.T(), 1, len(result))
-				assert.Equal(mdb.T(), "1", result[0].ID)
-				assert.Equal(mdb.T(), "testStatus1", result[0].Fields.Status.Name)
-				assert.Equal(mdb.T(), "testEmail1", result[0].Fields.Assignee.Email)
-				assert.Equal(mdb.T(), "testType1", result[0].Fields.Type.Name)
+				assert.Contains(mdb.T(), buffer.String(), "1\t-\tTickets Collected")
 			},
 		},
 		{
@@ -83,6 +89,12 @@ func TestCollectTickets(t *testing.T) {
 					return b.Name == activeBoards[0].Name
 				})).Return(ticketsToDelete).Once()
 
+				mdb.On("UpsertTicket", mock.MatchedBy(func(t db.TicketJSON) bool {
+					return t.ID == "5" && t.Fields.Status.Name == "testStatus1" &&
+						t.Fields.Assignee.Email == "testEmail1" &&
+						t.Fields.Type.Name == "testType1"
+				})).Once()
+
 				mdb.On("DeleteTicket", mock.MatchedBy(func(t db.Ticket) bool {
 					return t.Assignee == ticketsToDelete[0].Assignee
 				})).Once()
@@ -93,20 +105,19 @@ func TestCollectTickets(t *testing.T) {
 					mdb.AssertExpectations(mdb.T())
 					api.AssertExpectations(api.T())
 				}()
+				// saving logs
+				buffer := bytes.Buffer{}
+				utils.Logger.InfoLogger.SetOutput(&buffer)
+				// testing
 				var boards []db.CollectorTarget
 				getMock("testdata/db/collector_targets/collector-targets.json",
 					mdb.T(), &boards)
 				var activeBoards = []db.CollectorTarget{boards[0]}
 				activeBoards[0].API_URL = s.URL
-				resultChannel := make(chan *[]db.TicketJSON)
-				go collectTickets(activeBoards, mdb, resultChannel)
-				result := *<-resultChannel
+				collectTickets(activeBoards, mdb)
 
-				assert.Equal(mdb.T(), 1, len(result))
-				assert.Equal(mdb.T(), "5", result[0].ID)
-				assert.Equal(mdb.T(), "testStatus1", result[0].Fields.Status.Name)
-				assert.Equal(mdb.T(), "testEmail1", result[0].Fields.Assignee.Email)
-				assert.Equal(mdb.T(), "testType1", result[0].Fields.Type.Name)
+				assert.Contains(mdb.T(), buffer.String(), "1\t-\tTickets Collected")
+				assert.Contains(mdb.T(), buffer.String(), "1\t-\tTickets Removed")
 			},
 		},
 	}
diff --git a/pkg/collector/main.go b/pkg/collector/main.go
index c81df98d6ba2b9e6d1e3dabe994cd6940fdd05b0..442bbf3f6ad9aee2896996978e03c4977eb70c36 100644
--- a/pkg/collector/main.go
+++ b/pkg/collector/main.go
@@ -4,59 +4,11 @@ import (
 	"time"
 
 	"holocron/collector-jira-workflow/pkg/database"
-	"holocron/collector-jira-workflow/pkg/utils"
 )
 
 func Collect(db database.DB) {
-	startTime := time.Now()
-
-	utils.Logger.Info("Collecting boards...")
-	boards := collectBoards(db)
-	utils.Logger.Info("Saving boards...")
-	saveBoards(boards, db)
+	collectBoards(db)
 	activeBoards := db.GetActiveBoards()
-
-	utils.Logger.Info("Collecting workflow data...")
-	ticketsChannel := make(chan *[]database.TicketJSON)
-
-	go collectTickets(activeBoards, db, ticketsChannel)
-
-	tickets := <-ticketsChannel
-
-	utils.Logger.Info("Saving workflow data...")
-	saveTickets(tickets, db)
-	utils.Logger.Info("Workflow data saved.")
-
-	// set LastCollected after collection is done
+	collectTickets(activeBoards, db)
 	setLastUpdated(activeBoards, time.Now(), db)
-
-	utils.Logger.Infof("--Finished Collecting---\n"+
-		"%d\t-\tBoards\n"+
-		"%d\t-\tTickets\n"+
-		"---Time Elapsed - %.0f seconds---",
-		len(*boards),
-		len(*tickets),
-		time.Since(startTime).Seconds(),
-	)
-}
-
-func saveTickets(tickets *[]database.TicketJSON, db database.DB) {
-	for _, ticket := range *tickets {
-		db.UpsertTicket(ticket)
-	}
-}
-
-func saveBoards(boards *[]database.BoardJSON, db database.DB) {
-	for _, board := range *boards {
-		db.UpsertBoard(board)
-	}
-}
-func setLastUpdated(activeBoards []database.CollectorTarget, time time.Time,
-	db database.DB) {
-
-	for _, board := range activeBoards {
-		currentBoard := board.ToBoardJSON()
-		currentBoard.LastCollected = time
-		db.UpsertBoard(currentBoard)
-	}
 }
diff --git a/pkg/httpClient/request.go b/pkg/httpClient/request.go
index d13bd21d3f492d852fc1fa3419d28c81ca31f3a9..692ffa07b21f7c005e45f6c709c775009b83a4be 100644
--- a/pkg/httpClient/request.go
+++ b/pkg/httpClient/request.go
@@ -73,8 +73,17 @@ func getItemsInPage(url string, itemsPtr interface{}) error {
 }
 
 func GetBoards() *[]db.BoardJSON {
-	boards := &db.BoardsJSON{Boards: []db.BoardJSON{}}
 	const perPage = 50
+	var (
+		currentTime     = time.Now()
+		boards          = &db.BoardsJSON{Boards: []db.BoardJSON{}}
+		setCustomFields = func(boards []db.BoardJSON) {
+			for i, b := range boards {
+				boards[i].API_URL = fmt.Sprintf("%s/board/%d", config.API_URL, b.ID)
+				boards[i].LastCollected = currentTime
+			}
+		}
+	)
 	for startAt, hasNext := 0, true; hasNext; startAt += perPage {
 		var pageBoards db.BoardsJSON
 		if err := getItemsInPage(fmt.Sprintf("%s/board?startAt=%d", config.API_URL, startAt),
@@ -84,13 +93,22 @@ func GetBoards() *[]db.BoardJSON {
 		boards.Boards = append(boards.Boards, pageBoards.Boards...)
 		hasNext = !pageBoards.IsLast
 	}
+	setCustomFields(boards.Boards)
 
 	return &boards.Boards
 }
 
 func GetTickets(board db.CollectorTarget) *[]db.TicketJSON {
-	tickets := &db.TicketsJSON{Tickets: []db.TicketJSON{}}
 	const perPage = 100
+	var (
+		tickets         = &db.TicketsJSON{Tickets: []db.TicketJSON{}}
+		setCustomFields = func(tickets []db.TicketJSON) {
+			for i := range tickets {
+				tickets[i].BoardId = board.ID
+				tickets[i].BuildStatusHistory()
+			}
+		}
+	)
 	for startAt, next := 0, true; next; startAt += perPage {
 		var pageTickets db.TicketsJSON
 		if err := getItemsInPage(fmt.Sprintf(
@@ -103,6 +121,7 @@ func GetTickets(board db.CollectorTarget) *[]db.TicketJSON {
 		tickets.Tickets = append(tickets.Tickets, pageTickets.Tickets...)
 		next = pageTickets.Total > startAt+perPage
 	}
+	setCustomFields(tickets.Tickets)
 
 	return &tickets.Tickets
 }