diff --git a/plugins/network/example-graphs/nft_counters-1.png b/plugins/network/example-graphs/nft_counters-1.png
new file mode 100644
index 000000000..f78bed7b7
Binary files /dev/null and b/plugins/network/example-graphs/nft_counters-1.png differ
diff --git a/plugins/network/example-graphs/nft_counters-2.png b/plugins/network/example-graphs/nft_counters-2.png
new file mode 100644
index 000000000..690c4729c
Binary files /dev/null and b/plugins/network/example-graphs/nft_counters-2.png differ
diff --git a/plugins/network/example-graphs/nft_counters-day.png b/plugins/network/example-graphs/nft_counters-day.png
new file mode 100644
index 000000000..b7887acfc
Binary files /dev/null and b/plugins/network/example-graphs/nft_counters-day.png differ
diff --git a/plugins/network/example-graphs/nft_counters-week.png b/plugins/network/example-graphs/nft_counters-week.png
new file mode 100644
index 000000000..8099b04c4
Binary files /dev/null and b/plugins/network/example-graphs/nft_counters-week.png differ
diff --git a/plugins/network/nft_counters b/plugins/network/nft_counters
new file mode 100755
index 000000000..09b145a23
--- /dev/null
+++ b/plugins/network/nft_counters
@@ -0,0 +1,322 @@
+#!/usr/bin/python
+
+"""
+Munin plugin for monitoring counters in nftables. For more information on
+nftables see https://wiki.nftables.org/wiki-nftables/index.php/Counters
+
+=head1 NAME
+
+nft_counters - Munin Plugin for monitoring counters in nftables
+
+=head1 DESCRIPTION
+
+Plugin reads counters [1] from nftables and shows the associated values in bytes
+and packets. Which counters and/or values are to be shown can be configured
+(see L<below|"CONFIGURATION">).
+
+=head1 REQUIREMENTS
+
+Plugin runs on systems with nftables installed. It makes use of the excellent
+pymunin module, so that needs to be installed as well (see L<below|"ACKNOWLEDGEMENT">).
+
+=head1 CONFIGURATION
+
+Since reading nftables needs root permissions, so does this plugin. That makes
+the 'user root' setting in the configuration file mandatory.
+
+To further tune what should be graphed or not, you can adjust the configuration
+usually found in /etc/munin/plugin-conf.d/nft_counters:
+
+    [nft_counters]
+    user root
+
+    env.counters_exclude counter_one,counter_two
+    env.counters_include counter_this,counter_that
+    env.count_only [bytes | packets]
+
+=head2 env.counters_exclude
+
+Exclude counters from graph. Comma separated list of counters, as known to
+nftables (see 'nft list counters'), to exclude from graphing.
+
+=head2 env.counters_include
+
+Include counters in graph, I<exclusively>. Comma separated list of counters,
+as known to nftables (see 'nft list counters'), to include in graphing.
+B<If this doesn't match any counter, nothing will be graphed.>
+
+=head2 env.count_only
+
+Show values only in bytes or packets. Default both counters are shown.
+
+=head1 BUGS
+
+=head2 {fieldname}.info
+
+The {fieldname}.info should show the comment associated with the counter.
+However, the JSON output of 'nft' does not contain the comment attribute. So,
+for now, the plugin uses the counter name for {fieldname}.info. There is an
+open L<bug|https://bugzilla.netfilter.org/show_bug.cgi?id=1611> upstream.
+
+=head1 AUTHOR
+
+Written and Blessed by (Holy) Penguinpee <L<devel@penguinpee.nl>>
+
+=head1 LICENSE
+
+GPLv3
+
+=head1 ACKNOWLEDGEMENT
+
+This plugin makes use of the excellent pymunin [2] module by Ali Onur Uyar,
+adapted to Python3 [3] and available on PyPI as PyMunin3 [4].
+
+The implementation of nftables interaction is based on the very helpful
+examples [5] provided by Arturo Borrero Gonzalez.
+
+=head1 SEE ALSO
+
+=over
+
+=item [1] L<https://wiki.nftables.org/wiki-nftables/index.php/Counters>
+
+=item [2] L<https://github.com/aouyar/PyMunin>
+
+=item [3] L<https://github.com/penguinpee/PyMunin3>
+
+=item [4] L<https://pypi.org/project/PyMunin3>
+
+=item [5] L<https://github.com/aborrero/python-nftables-tutorial>
+
+=back
+
+=head1 MAGIC MARKERS
+
+ #%# family=auto
+ #%# capabilities=autoconf
+
+=cut
+"""
+
+import sys
+
+try:
+    from nftables import Nftables
+    from nftables import json
+except Exception as err:
+    print("Unable to load nftables module.")
+    sys.exit(err)
+
+try:
+    from pymunin import MuninPlugin, MuninGraph, muninMain
+except Exception as err:
+    print("Unable to load PyMunin module.")
+    sys.exit(err)
+
+
+def _find_objects(ruleset, type):
+    # isn't this pure python?
+    return [o[type] for o in ruleset if type in o]
+
+
+def nft_cmd(nftlib, cmd):
+    rc, output, error = nftlib.cmd(cmd)
+    if rc != 0:
+        # do proper error handling here, exceptions etc
+        raise RuntimeError("Error running cmd 'nft {}'".format(cmd))
+
+    if len(output) == 0:
+        # more error control
+        raise RuntimeError("ERROR: no output from libnftables")
+
+    # transform the libnftables JSON output into generic python data structures
+    ruleset = json.loads(output)["nftables"]
+
+    # validate we understand the libnftables JSON schema version.
+    # if the schema bumps version, this program might require updates
+    for metainfo in _find_objects(ruleset, "metainfo"):
+        if metainfo["json_schema_version"] > 1:
+            print("WARNING: we might not understand the JSON produced by libnftables")
+
+    return ruleset
+
+
+def getCounters():
+
+    nft = Nftables()
+    nft.set_json_output(True)
+    nft.set_handle_output(True)
+
+    ruleset = nft_cmd(nft, "list counters")
+    counters = _find_objects(ruleset, "counter")
+
+    if len(counters) > 0:
+        return counters
+    else:
+        raise ValueError("No counters in nftables")
+
+
+class MuninNftCountersPlugin(MuninPlugin):
+
+    """
+    Munin Plugin for nftables counters
+    """
+
+    plugin_name = "nft_counters"
+    isMultigraph = True
+
+    def __init__(self, argv=(), env=None, debug=False):
+
+        """
+
+        Initialize Munin Plugin
+
+        Parameters
+        ----------
+        argv : TYPE, optional
+            List of commandline arguments. The default is ().
+        env : TYPE, optional
+            Dictionary of environment variables. The default is None.
+        debug : TYPE, optional
+            Print debugging messages. The default is False.
+
+        Returns
+        -------
+        None.
+
+        """
+
+        MuninPlugin.__init__(self, argv, env, debug)
+
+        # Munin graph parameters
+        graph_category = "network"
+
+        try:
+            self.counters = getCounters()
+        except ValueError:
+            if self._argv[1] == "autoconf":
+                return
+            else:
+                print(
+                    "# No counters in nftables. Try adding some first.",
+                    "# See 'munin-doc %s' for more information." % self.plugin_name,
+                    sep="\n",
+                )
+                raise
+        except Exception:
+            if self._argv[1] == "autoconf":
+                return
+            else:
+                print(
+                    "# Plugin needs to be run as root since nftables can only be",
+                    "# run as root.",
+                    "#",
+                    "# Use the following setting in the configuration file",
+                    "# to enable root privileges:",
+                    "#",
+                    "# [%s]" % self.plugin_name,
+                    "# user root",
+                    sep="\n",
+                )
+                raise
+
+        count_only = self.envGet("count_only")
+
+        # Create the graphs
+        if not (count_only == "bytes"):
+            graph_packets = MuninGraph(
+                "nftables counters (packets)",
+                graph_category,
+                vlabel="packets / second",
+                args="--base 1000",
+            )
+        if not (count_only == "packets"):
+            graph_bytes = MuninGraph(
+                "nftables counters (bytes)",
+                graph_category,
+                vlabel="bytes / second",
+                args="--base 1024",
+            )
+
+        # Define filter to allow for tuning of counters graphed
+        self.envRegisterFilter("counters")
+
+        # add counters as field to each graph (packets and bytes)
+        for counter in self.counters:
+            # JSON output does not contain "comment" attribute.
+            # Until it does, use counter name as info
+            try:
+                field_info = counter["comment"]
+            except Exception:
+                field_info = counter["name"]
+
+            if self.envCheckFilter("counters", counter["name"]):
+                if not (count_only == "bytes"):
+                    graph_packets.addField(
+                        counter["name"],
+                        counter["name"],
+                        min=0,
+                        type="DERIVE",
+                        info=field_info,
+                    )
+                if not (count_only == "packets"):
+                    graph_bytes.addField(
+                        counter["name"],
+                        counter["name"],
+                        min=0,
+                        type="DERIVE",
+                        info=field_info,
+                    )
+
+        if not (count_only == "bytes"):
+            self.appendGraph("nft_counters_packets", graph_packets)
+        if not (count_only == "packets"):
+            self.appendGraph("nft_counters_bytes", graph_bytes)
+
+    def retrieveVals(self):
+
+        """
+        Get values and add them to the graphs
+
+        Returns
+        -------
+        None.
+
+        """
+
+        # add values for each field
+        for counter in self.counters:
+            if self.envCheckFilter("counters", counter["name"]):
+                if self.hasGraph("nft_counters_packets"):
+                    self.setGraphVal(
+                        "nft_counters_packets", counter["name"], counter["packets"]
+                    )
+                if self.hasGraph("nft_counters_bytes"):
+                    self.setGraphVal(
+                        "nft_counters_bytes", counter["name"], counter["bytes"]
+                    )
+
+    def autoconf(self):
+        """
+        Implements Munin Plugin Auto-Configuration Option.
+
+        Returns
+        -------
+        bool
+            True if plugin can be auto-configured.
+
+        """
+
+        try:
+            getCounters()
+            return True
+        except Exception:
+            return False
+
+
+def main():
+    sys.exit(muninMain(MuninNftCountersPlugin))
+
+
+if __name__ == "__main__":
+    main()