diff --git a/tools/relay-checker/config.go b/tools/relay-checker/config.go
new file mode 100644
index 0000000000000000000000000000000000000000..9096faf6f22fe6d7349d5a473c167ce04e17ca3f
--- /dev/null
+++ b/tools/relay-checker/config.go
@@ -0,0 +1,46 @@
+package main
+
+import (
+	"github.com/iotaledger/goshimmer/packages/parameter"
+)
+
+var (
+	nodes    []string
+	target   = ""
+	txnAddr  = "GOSHIMMER99TEST999999999999999999999999999999999999999999999999999999999999999999"
+	txnData  = "TEST99BROADCAST99DATA"
+	cooldown = 2
+	maxQuery = 1
+)
+
+func LoadConfig() {
+	if err := parameter.FetchConfig(false); err != nil {
+		panic(err)
+	}
+}
+
+func SetConfig() {
+	if parameter.NodeConfig.GetString(CFG_TARGET_NODE) == "" {
+		panic("Set the target node address\n")
+	}
+	target = parameter.NodeConfig.GetString(CFG_TARGET_NODE)
+
+	if len(parameter.NodeConfig.GetStringSlice(CFG_TEST_NODES)) == 0 {
+		panic("Set node addresses\n")
+	}
+	nodes = append(nodes, parameter.NodeConfig.GetStringSlice(CFG_TEST_NODES)...)
+
+	// optional settings
+	if parameter.NodeConfig.GetString(CFG_TXN_ADDRESS) != "" {
+		txnAddr = parameter.NodeConfig.GetString(CFG_TXN_ADDRESS)
+	}
+	if parameter.NodeConfig.GetString(CFG_DATA) != "" {
+		txnData = parameter.NodeConfig.GetString(CFG_DATA)
+	}
+	if parameter.NodeConfig.GetInt(CFG_COOL_DOWN_TIME) > 0 {
+		cooldown = parameter.NodeConfig.GetInt(CFG_COOL_DOWN_TIME)
+	}
+	if parameter.NodeConfig.GetInt(CFG_MAX_QUERY) > 0 {
+		maxQuery = parameter.NodeConfig.GetInt(CFG_MAX_QUERY)
+	}
+}
diff --git a/tools/relay-checker/config.json b/tools/relay-checker/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..d7c0df551297552275129aa199deb983d1b5bc98
--- /dev/null
+++ b/tools/relay-checker/config.json
@@ -0,0 +1,12 @@
+{
+  "relaycheck": {
+    "targetnode": "http://127.0.0.1:8080",
+    "nodes": [
+        "http://127.0.0.1:8080"
+    ],
+    "txnaddress": "SHIMMER99TEST99999999999999999999999999999999999999999999999999999999999999999999", 
+    "data": "TEST99BROADCAST99DATA",
+    "cooldowntime": 10,
+    "maxquery": 2 
+  }
+}
diff --git a/tools/relay-checker/main.go b/tools/relay-checker/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..189babf7ea79072579c5872a5209a9853989109a
--- /dev/null
+++ b/tools/relay-checker/main.go
@@ -0,0 +1,72 @@
+package main
+
+import (
+	"fmt"
+	"time"
+
+	client "github.com/iotaledger/goshimmer/client"
+	"github.com/iotaledger/goshimmer/packages/errors"
+	"github.com/iotaledger/iota.go/trinary"
+)
+
+func testBroadcastData(api *client.GoShimmerAPI) (trinary.Hash, error) {
+	txnHash, err := api.BroadcastData(txnAddr, txnData)
+	if err != nil {
+		return "", errors.Wrapf(err, "Broadcast failed")
+	}
+	return txnHash, nil
+}
+
+func testTargetGetTransactions(api *client.GoShimmerAPI, txnHash trinary.Hash) error {
+	// query target node for broadcasted data
+	_, err := api.GetTransactions([]trinary.Hash{txnHash})
+	if err != nil {
+		return errors.Wrapf(err, "Query target failed")
+	}
+	return nil
+}
+
+func testNodesGetTransactions(txnHash trinary.Hash) error {
+	// query nodes node for broadcasted data
+	for _, n := range nodes {
+		nodesApi := client.NewGoShimmerAPI(n)
+		_, err := nodesApi.GetTransactions([]trinary.Hash{txnHash})
+		if err != nil {
+			return errors.Wrapf(err, "Query %s failed", n)
+		}
+		fmt.Printf("txn found in %s\n", n)
+	}
+	return nil
+}
+
+func main() {
+	LoadConfig()
+	SetConfig()
+
+	api := client.NewGoShimmerAPI(target)
+	for i := 0; i < maxQuery; i++ {
+		txnHash, err := testBroadcastData(api)
+		if err != nil {
+			fmt.Printf("%s\n", err)
+			break
+		}
+		fmt.Printf("txnHash: %s\n", txnHash)
+
+		// cooldown time
+		time.Sleep(time.Duration(cooldown) * time.Second)
+
+		// query target node
+		err = testTargetGetTransactions(api, txnHash)
+		if err != nil {
+			fmt.Printf("%s\n", err)
+			break
+		}
+
+		// query nodes node
+		err = testNodesGetTransactions(txnHash)
+		if err != nil {
+			fmt.Printf("%s\n", err)
+			break
+		}
+	}
+}
diff --git a/tools/relay-checker/parameters.go b/tools/relay-checker/parameters.go
new file mode 100644
index 0000000000000000000000000000000000000000..b1ee2b9b5ab6fa5885237e980ff329a33b4bdd13
--- /dev/null
+++ b/tools/relay-checker/parameters.go
@@ -0,0 +1,23 @@
+package main
+
+import (
+	flag "github.com/spf13/pflag"
+)
+
+const (
+	CFG_TARGET_NODE    = "relaycheck.targetNode"
+	CFG_TEST_NODES     = "relaycheck.nodes"
+	CFG_TXN_ADDRESS    = "relaycheck.txnAddress"
+	CFG_DATA           = "relaycheck.data"
+	CFG_COOL_DOWN_TIME = "relaycheck.cooldownTime"
+	CFG_MAX_QUERY      = "relaycheck.maxQuery"
+)
+
+func init() {
+	flag.StringSlice(CFG_TEST_NODES, []string{""}, "list of trusted entry nodes for auto peering")
+	flag.String(CFG_TARGET_NODE, "http://127.0.0.1:8080", "target node to test")
+	flag.String(CFG_TXN_ADDRESS, "SHIMMER99TEST99999999999999999999999999999999999999999999999999999999999999999999", "transaction address")
+	flag.String(CFG_DATA, "TEST99BROADCAST99DATA", "data to broadcast")
+	flag.Int(CFG_COOL_DOWN_TIME, 10, "cooldown time after broadcast data")
+	flag.Int(CFG_MAX_QUERY, 1, "the repeat times of relay-checker")
+}